1. std::future
std::future<T>
用于异步获取任务的结果,结果只能被获取一次。对象不可复制,但可移动。
关键特性:
get()
调用后,future
状态失效(valid()
返回false
)。- 析构时,若关联的异步结果未就绪且是最后一个引用,可能阻塞等待结果(取决于启动策略)。
常用成员函数:
-
get()
获取结果,调用后valid()
变为false
。若结果未就绪,阻塞当前线程。
若任务抛异常,get()
会重新抛出该异常。T get(); // T 可能为 void、引用或值类型
-
wait()
阻塞直到任务完成,不获取结果。void wait();
-
wait_for()
等待指定时间,返回状态future_status
(ready
、timeout
或deferred
)。template <class Rep, class Period> std::future_status wait_for(const std::chrono::duration<Rep, Period>& rel_time);
-
wait_until()
等待到指定时间点,返回状态future_status
。template <class Clock, class Duration> std::future_status wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time);
-
valid()
检查是否关联有效结果(例如未调用get()
)。bool valid() const noexcept;
-
share()
转为std::shared_future<T>
,允许共享结果。std::shared_future<T> share();
2. std::shared_future
std::shared_future<T>
允许共享异步结果,可被多次调用 get()
。对象可复制。
关键特性:
get()
可多次调用,每次返回结果的副本(若T
非引用)。- 若
T
为引用类型(如T&
),需注意引用的有效性。
常用成员函数:
-
get()
返回结果副本(若T
非引用)。若T
为void
,无返回值。const T& get() const; // T 非 void 时的返回类型可能不同
-
wait()
/wait_for()
/wait_until()
同std::future
。 -
valid()
同std::future
。
3. std::packaged_task
std::packaged_task<Function>
包装可调用对象(如函数、lambda),将其结果绑定到 std::future
。对象不可复制,但可移动。
关键特性:
- 调用
operator()
后,结果被存储到关联的future
中。 - 若多次调用
operator()
或未关联可调用对象,抛出std::future_error
。
常用成员函数:
-
构造函数
需提供可调用对象。默认构造的packaged_task
为空(valid() == false
)。explicit packaged_task(Function&& f);
-
operator()
执行任务并存储结果或异常。若已调用过或对象为空,抛出异常。void operator()(Args... args);
-
get_future()
返回关联的std::future<T>
。若已调用或对象为空,抛出异常。std::future<T> get_future();
-
swap()
交换两个packaged_task
的内容。void swap(packaged_task& other) noexcept;
-
reset()
(C++11 起)
重置任务,允许重新绑定新的可调用对象。void reset();
4. std::promise
std::promise<T>
用于显式设置异步结果或异常,关联的 std::future
可获取结果。对象不可复制,但可移动。
关键特性:
- 若
promise
析构前未设置结果,关联的future
会收到std::future_error
(broken_promise
)。 - 可设置结果或异常,但只能设置一次,重复设置抛出
std::future_error
。
常用成员函数:
-
构造函数
默认构造的promise
有效。移动构造函数允许转移所有权。promise(); promise(promise&& other) noexcept;
-
set_value()
设置结果。若T
为void
,无参调用。void set_value(const T& value); void set_value(T&& value); void set_value(); // 当 T 为 void 时
-
set_exception()
设置异常指针(如捕获的异常通过std::current_exception()
)。void set_exception(std::exception_ptr p);
-
set_value_at_thread_exit()
设置结果,但延迟到当前线程退出时通知future
。void set_value_at_thread_exit(const T& value);
-
set_exception_at_thread_exit()
类似set_value_at_thread_exit
,但设置异常。void set_exception_at_thread_exit(std::exception_ptr p);
-
get_future()
返回关联的std::future<T>
,只能调用一次。std::future<T> get_future();
-
swap()
交换两个promise
的内容。void swap(promise& other) noexcept;
总结对比
组件 | 核心功能 | 是否可复制 | 是否可移动 | 结果获取次数 | 特殊行为 |
---|---|---|---|---|---|
std::future | 单次获取异步结果 | 否 | 是 | 一次 | get() 后失效,析构可能阻塞 |
std::shared_future | 共享异步结果 | 是 | 是 | 多次 | get() 返回副本或引用 |
std::packaged_task | 包装可调用对象,绑定结果到 future | 否 | 是 | 一次 | 调用 operator() 后结果就绪 |
std::promise | 显式设置结果或异常 | 否 | 是 | 一次 | 未设置结果时析构会触发 broken_promise ,可设置延迟通知 |
关键注意事项
- 异常传递:所有组件的
get()
会传递任务中抛出的异常。 - 有效性检查:调用
get_future()
、get()
或set_value()
前需确保对象有效(如valid()
返回true
)。 - 线程安全:除
std::shared_future
的const
成员函数外,其他组件的方法通常不保证线程安全。 - 移动语义:
std::future
、std::packaged_task
和std::promise
支持移动语义,避免复制。 - 生命周期管理:确保
promise
或packaged_task
的生命周期长于关联的future
操作,防止悬空引用。