商城首页欢迎来到中国正版软件门户

您的位置:首页 >C++异步编程:future与promise详解

C++异步编程:future与promise详解

  发布于2026-03-14 阅读(0)

扫一扫,手机访问

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

c++怎么使用future和promise_c++异步编程【详解】

std::promise 和 std::future 必须配对使用,不能单独构造 valid 的 future

直接调用 std::future{} 得到的是空(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)。

  • 推荐用 std::packaged_task 封装 callable + promise,天然支持 move 到线程
  • 避免裸指针或引用传递 promise;用 std::shared_ptr> 需额外同步,一般没必要
  • lambda 捕获 promise 时务必用 move:[p = std::move(promise)]() mutable { p.set_value(…); }
future 和 promise 的核心契约很简单:一写一读、单次消费、状态绑定不可解耦。多数 crash 或 hang 都来自违背这三条。真正难的不是语法,而是判断「谁该拥有 promise」「谁该持有 future」「超时后怎么取消」——C++ 标准库本身不提供取消机制,这部分得自己设计信号或用第三方库。
本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注