Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
task.h
Go to the documentation of this file.
1
8
9/*
10Copyright (c) 2026 MrXie1109
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29*/
30
31#pragma once
32#include <functional>
33#include <future>
34#include <memory>
35#include <thread>
36
37#include "../core/sfinae.h"
38#include "./event.h"
39
40namespace console {
50 template <class T>
51 class Task {
52 std::future<T> future_;
53 std::thread thread_;
54 std::unique_ptr<Event> event_;
55
56 public:
58 Task() = default;
59
68 template <class F, class... Args>
69 explicit Task(F &&f, Args &&...args) {
70 start(std::forward<F>(f), std::forward<Args>(args)...);
71 }
72
74 Task(const Task &) = delete;
76 Task &operator=(const Task &) = delete;
77
82 Task(Task &&other) noexcept :
83 future_(std::move(other.future_)),
84 thread_(std::move(other.thread_)), //
85 event_(std::move(other.event_)) {}
86
92 Task &operator=(Task &&other) noexcept {
93 if (this != &other) {
94 if (event_) event_->set();
95 if (thread_.joinable()) thread_.join();
96 future_ = std::move(other.future_);
97 thread_ = std::move(other.thread_);
98 event_ = std::move(other.event_);
99 }
100 return *this;
101 }
102
107 if (event_) event_->set();
108 if (thread_.joinable()) thread_.join();
109 }
110
119 template <class F, class... Args>
120 typename std::enable_if<
121 !is_callable<F, const Event &, Args...>::value>::type
122 start(F &&f, Args &&...args) {
123 auto bound_task
124 = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
125 std::packaged_task<T()> task(std::move(bound_task));
126 future_ = task.get_future();
127 thread_ = std::thread(std::move(task));
128 }
129
130 template <class F, class... Args>
131 typename std::enable_if<
132 is_callable<F, const Event &, Args...>::value>::type
133 start(F &&f, Args &&...args) {
134 if (!event_) event_.reset(new Event());
135 start(std::forward<F>(f),
136 std::cref(*event_),
137 std::forward<Args>(args)...);
138 }
139
144 T get() { return future_.get(); }
145
150 bool valid() { return future_.valid(); }
151
153 void wait() const { future_.wait(); }
154
162 template <class Rep, class Period>
163 std::future_status
164 wait_for(const std::chrono::duration<Rep, Period> &timeout) const {
165 return future_.wait_for(timeout);
166 }
167
173 std::future_status wait_for(Time timeout) const {
174 return future_.wait_for(std::chrono::nanoseconds(timeout.count()));
175 }
176
182 std::future_status wait_for(double seconds) const {
183 return future_.wait_for(std::chrono::duration<double>(seconds));
184 }
185
191 template <class Clock, class Duration>
192 std::future_status wait_until(
193 const std::chrono::time_point<Clock, Duration> &time_point) const {
194 return future_.wait_until(time_point);
195 }
196
201 std::future_status status() const {
202 return future_.wait_for(std::chrono::nanoseconds(0));
203 }
204
209 void cancel() {
210 if (status() == std::future_status::ready) return;
211 if (event_) event_->set();
212 std::promise<T> promise;
213 future_ = promise.get_future();
214 promise.set_exception(std::make_exception_ptr(
215 AsyncError("Task has been cancelled.")));
216 }
217 };
218
229 template <class T>
231 std::shared_future<T> future_;
232 std::shared_ptr<std::thread> thread_;
233 std::shared_ptr<Event> event_;
234 std::shared_ptr<std::once_flag> flag_;
235
240 static void thread_deleter(std::thread *t) {
241 if (t && t->joinable()) t->join();
242 }
243
248 static void event_deleter(Event *e) { e->set(); }
249
250 public:
252 SharedTask() : flag_(new std::once_flag()) {}
253
262 template <class F,
263 class... Args,
264 class = typename std::enable_if<
265 is_callable<F, Args...>::value
266 || is_callable<F, const Event &, Args...>::value>::type>
267 explicit SharedTask(F &&f, Args &&...args) :
268 flag_(new std::once_flag()) {
269 start(std::forward<F>(f), std::forward<Args>(args)...);
270 }
271
276 SharedTask(const SharedTask &other) :
277 future_(other.future_), //
278 thread_(other.thread_), //
279 event_(other.event_), //
280 flag_(other.flag_) {}
281
288 future_ = other.future_;
289 thread_ = other.thread_;
290 event_ = other.event_;
291 flag_ = other.flag_;
292 return *this;
293 }
294
299 SharedTask(SharedTask &&other) noexcept :
300 future_(std::move(other.future_)),
301 thread_(std::move(other.thread_)), //
302 event_(std::move(other.event_)), //
303 flag_(std::move(other.flag_)) {}
304
310 SharedTask &operator=(SharedTask &&other) noexcept {
311 if (this != &other) {
312 future_ = std::move(other.future_);
313 thread_ = std::move(other.thread_);
314 event_ = std::move(other.event_);
315 flag_ = std::move(other.flag_);
316 }
317 return *this;
318 }
319
323 ~SharedTask() = default;
324
333 template <class F, class... Args>
334 typename std::enable_if<
335 !is_callable<F, const Event &, Args...>::value>::type
336 start(F &&f, Args &&...args) {
337 auto bound_task
338 = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
339 std::packaged_task<T()> task(std::move(bound_task));
340 future_ = task.get_future().share();
341 thread_ = std::shared_ptr<std::thread>(
342 new std::thread(std::move(task)), thread_deleter);
343 }
344
345 template <class F, class... Args>
346 typename std::enable_if<
347 is_callable<F, const Event &, Args...>::value>::type
348 start(F &&f, Args &&...args) {
349 if (!event_)
350 event_ = std::shared_ptr<Event>(new Event(), event_deleter);
351 start(std::forward<F>(f),
352 std::cref(*event_),
353 std::forward<Args>(args)...);
354 }
355
360 T get() { return future_.get(); }
361
366 bool valid() { return future_.valid(); }
367
369 void wait() const { future_.wait(); }
370
378 template <class Rep, class Period>
379 std::future_status
380 wait_for(const std::chrono::duration<Rep, Period> &timeout) const {
381 return future_.wait_for(timeout);
382 }
383
389 std::future_status wait_for(Time timeout) const {
390 return future_.wait_for(std::chrono::nanoseconds(timeout.count()));
391 }
392
398 std::future_status wait_for(double seconds) const {
399 return future_.wait_for(std::chrono::duration<double>(seconds));
400 }
401
407 template <class Clock, class Duration>
408 std::future_status wait_until(
409 const std::chrono::time_point<Clock, Duration> &time_point) const {
410 return future_.wait_until(time_point);
411 }
412
417 std::future_status status() const {
418 return future_.wait_for(std::chrono::nanoseconds(0));
419 }
420
426 void cancel() {
427 std::call_once(*flag_, [this] {
428 if (status() == std::future_status::ready) return;
429 if (event_) event_->set();
430 std::promise<T> promise;
431 future_ = promise.get_future().share();
432 promise.set_exception(std::make_exception_ptr(
433 AsyncError("SharedTask has been cancelled.")));
434 });
435 }
436 };
437}
AsyncError(const std::string &msg)
构造 ConsoleError。
Definition csexc.h:193
线程同步事件类,用于线程间通信。
Definition event.h:42
Event()
默认构造函数,初始化事件标志为 false。
Definition event.h:49
void set()
设置事件标志为 true,并通知所有等待的线程。
Definition event.h:52
std::shared_ptr< Event > event_
事件标志
Definition task.h:233
std::future_status wait_for(double seconds) const
等待异步任务完成,最多等待指定时间。
Definition task.h:398
SharedTask & operator=(const SharedTask &other)
拷贝赋值运算符。
Definition task.h:287
std::enable_if< is_callable< F, constEvent &, Args... >::value >::type start(F &&f, Args &&...args)
Definition task.h:348
std::future_status wait_for(const std::chrono::duration< Rep, Period > &timeout) const
等待异步任务完成,最多等待指定时间。
Definition task.h:380
SharedTask(F &&f, Args &&...args)
构造函数,接受一个可调用对象和参数,启动异步任务。
Definition task.h:267
static void event_deleter(Event *e)
事件删除器,用于在 std::shared_ptr 销毁时自动调用。
Definition task.h:248
SharedTask & operator=(SharedTask &&other) noexcept
移动赋值运算符。
Definition task.h:310
T get()
获取异步任务的返回值。
Definition task.h:360
std::shared_ptr< std::thread > thread_
任务执行的线程
Definition task.h:232
SharedTask(SharedTask &&other) noexcept
移动构造函数。
Definition task.h:299
std::shared_future< T > future_
任务的返回值
Definition task.h:231
SharedTask()
默认构造函数。
Definition task.h:252
std::future_status wait_until(const std::chrono::time_point< Clock, Duration > &time_point) const
等待异步任务完成,最多等待指定时间。
Definition task.h:408
void wait() const
等待异步任务完成。
Definition task.h:369
void cancel()
取消异步任务。
Definition task.h:426
~SharedTask()=default
析构函数。
std::enable_if<!is_callable< F, constEvent &, Args... >::value >::type start(F &&f, Args &&...args)
启动异步任务。
Definition task.h:336
SharedTask(const SharedTask &other)
拷贝构造函数。
Definition task.h:276
std::future_status status() const
获取异步任务的状态。
Definition task.h:417
std::shared_ptr< std::once_flag > flag_
取消标志
Definition task.h:234
std::future_status wait_for(Time timeout) const
等待异步任务完成,最多等待指定时间。
Definition task.h:389
static void thread_deleter(std::thread *t)
线程删除器,用于在 std::shared_ptr 销毁时自动调用。
Definition task.h:240
bool valid()
检查异步任务是否有效。
Definition task.h:366
~Task()
析构函数。
Definition task.h:106
Task & operator=(Task &&other) noexcept
移动赋值运算符。
Definition task.h:92
Task()=default
默认构造函数。
Task(F &&f, Args &&...args)
构造函数,接受一个可调用对象和参数,启动异步任务。
Definition task.h:69
std::future_status wait_until(const std::chrono::time_point< Clock, Duration > &time_point) const
等待异步任务完成,最多等待指定时间。
Definition task.h:192
void cancel()
取消异步任务。
Definition task.h:209
std::thread thread_
任务执行的线程
Definition task.h:53
std::future_status wait_for(const std::chrono::duration< Rep, Period > &timeout) const
等待异步任务完成,最多等待指定时间。
Definition task.h:164
Task & operator=(const Task &)=delete
删除拷贝赋值运算符。
Task(Task &&other) noexcept
移动构造函数。
Definition task.h:82
std::enable_if< is_callable< F, constEvent &, Args... >::value >::type start(F &&f, Args &&...args)
Definition task.h:133
bool valid()
检查异步任务是否有效。
Definition task.h:150
std::future_status wait_for(Time timeout) const
等待异步任务完成,最多等待指定时间。
Definition task.h:173
T get()
获取异步任务的返回值。
Definition task.h:144
std::enable_if<!is_callable< F, constEvent &, Args... >::value >::type start(F &&f, Args &&...args)
启动异步任务。
Definition task.h:122
std::future_status wait_for(double seconds) const
等待异步任务完成,最多等待指定时间。
Definition task.h:182
std::future_status status() const
获取异步任务的状态。
Definition task.h:201
void wait() const
等待异步任务完成。
Definition task.h:153
std::unique_ptr< Event > event_
事件标志
Definition task.h:54
Task(const Task &)=delete
删除拷贝构造函数。
std::future< T > future_
任务的返回值
Definition task.h:52
表示以纳秒为单位的时间量,支持单位转换、算术运算和自动选择合适的输出单位。
Definition time.h:57
intmax_t count() const
获取纳秒数。
Definition time.h:68
提供线程同步的 Event 类,支持设置、清除、等待和超时等待等操作。
is_callable_impl< F(Args...), void > is_callable
Definition sfinae.h:82
本库所有组件所在的顶层命名空间。
Time seconds(double n)
静态函数,构造秒。
Definition time.h:178
@ T
Definition kb.h:99
提供编译期类型特征检测(SFINAE 工具), 用于判断容器、可调用对象、迭代器、下标访问、字符串、可打印类型、字符类型等。