std::promise与std::future必须配对使用,前者为写端设置值/异常(仅一次),后者为读端获取结果(get后invalid);推荐优先用std::async创建future以避免生命周期和异常传递错误。

std::promise 和 std::future 必须配对使用,不能单独构造 valid 的 future
直接调用 std::future<int>{}</int> 得到的是空(invalid)对象,调用 get() 会抛出 std::future_error: No associated state。必须通过 std::promise::get_future() 获取绑定状态的 future。
-
std::promise是“写端”,负责设置值或异常;std::future是“读端”,负责等待并取值 - 一个
promise只能调用一次set_value()或set_exception(),重复调用导致std::future_error: Promise already satisfied -
future调用get()后即变为 invalid,再次调用get()也会报错
std::async 是最安全的 future 创建方式,比手动 manage promise 更少出错
手写 promise/future 容易漏掉移动语义、线程生命周期、异常传递等细节;std::async 自动处理这些,并返回 ready 或 deferred 的 future。
- 默认启动策略是
std::launch::async | std::launch::deferred,具体行为由实现决定;显式指定std::launch::async才确保异步执行 - 如果函数返回引用类型,
std::async返回的future里存的是拷贝(除非返回std::reference_wrapper) - 不保存
future对象会导致异步任务被阻塞等待(析构时若未就绪会同步等待完成)
auto f = std::async(std::launch::async, []{ return 42; });
int x = f.get(); // OK
// 若此处没接住 f,析构时会卡住主线程
wait_for 和 wait_until 不会取值,只是轮询状态;get 才真正消费结果
误以为 wait_for 能拿到值,结果仍需再调 get() —— 这是常见混淆点。且 get() 是阻塞+消费操作,不可重入。
-
future.wait_for(std::chrono::seconds(1)) == std::future_status::ready表示可安全调用get() -
wait_for返回timeout时,future仍有效,可继续等或放弃 - 对
std::shared_future可多次调用get(),但普通future不行
跨线程传递 promise/future 要注意所有权和生命周期
把 std::promise move 到线程里没问题,但若在线程外提前析构了它,而线程还没调 set_value(),就会导致 future.get() 永远挂起(deadlock)。
立即学习“C++免费学习笔记(深入)”;
- 推荐用
std::packaged_task封装 callable + promise,天然支持 move 到线程 - 避免裸指针或引用传递
promise;用std::shared_ptr<:promise>></:promise>需额外同步,一般没必要 - lambda 捕获
promise时务必用 move:[p = std::move(promise)]() mutable { p.set_value(…); }











