std::promise和std::future用于线程间传递异步结果,生产者通过promise设置值,消费者通过future获取结果,实现解耦与同步。

在C++多线程编程中,std::promise 和 std::future 提供了一种简洁高效的线程间通信方式,用于传递异步操作的结果。一个线程可以通过 std::promise 设置值或异常,另一个线程则通过关联的 std::future 获取该结果,实现解耦与异步等待。
基本概念与配合机制
std::promise 是一个可写的一次性容器,用于设置某个值或异常;std::future 是其对应的只读代理,用于在未来某个时间点获取这个值。两者通过共享状态关联。
典型使用流程如下:
- 创建一个 std::promise
对象 - 调用其 get_future() 方法获得对应的 std::future
- 将 promise 移动到生产者线程,future 移动到消费者线程
- 生产者调用 promise.set_value() 或 set_exception()
- 消费者调用 future.get() 阻塞等待并取得结果
简单示例:异步计算返回结果
以下代码展示主线程启动工作线程执行任务,并通过 promise/future 获取结果:
立即学习“C++免费学习笔记(深入)”;
#include#include #include void compute(std::promise && prom) { int result = 42; // 模拟耗时计算 prom.set_value(result); } int main() { std::promise prom; std::future fut = prom.get_future(); std::thread t(compute, std::move(prom)); std::cout << "等待结果...\n"; int value = fut.get(); // 阻塞直到结果可用 std::cout << "得到结果: " << value << "\n"; t.join(); return 0; }
注意:必须确保 promise 被正确移动,且只能调用一次 set_value,否则会抛出异常。
异常传递与错误处理
除了正常值,std::promise 还能传递异常,使消费者端能捕获并处理错误:
void may_fail(std::promise&& prom) { try { // 模拟可能失败的操作 throw std::runtime_error("计算失败"); } catch (...) { prom.set_exception(std::current_exception()); } }
在调用 future.get() 时,若设置了异常,则该异常会被重新抛出,可在 catch 块中处理。
应用场景与注意事项
这种机制适用于需要等待单次异步结果的场景,如:
- 后台加载配置并通知主线程
- 分离计算与结果消费逻辑
- 实现简单的任务完成通知(通过 set_value_at_thread_exit)
关键注意事项:
- 每个 promise 只能设置一次结果,重复调用 set_value 会引发异常
- 若 promise 被销毁前未设置值,future.get() 会抛出 std::future_error
- 避免死锁:不要在同一个线程中创建并等待同一个 future,除非有其他线程负责设置值
- 移动语义:promise 不可复制,必须使用移动操作在线程间传递
基本上就这些。合理使用 std::promise 和 std::future,可以写出清晰、安全的异步通信代码,避免手动管理互斥量和条件变量的复杂性。









