1. std::promise基础概念解析
std::promise是C++11标准库中引入的线程间通信机制,与std::future配合使用可实现跨线程的值传递和状态通知。这个模板类的核心设计理念是"承诺-未来"模式:一个线程通过promise对象承诺在未来某个时刻提供数据,另一个线程则通过关联的future对象获取这个可能尚未准备好的数据。
1.1 核心工作机制
每个std::promise实例都关联着一个共享状态(shared state),这个状态可能处于三种情况:
- 尚未就绪(结果未计算)
- 已存储值(包括void特化版本)
- 已存储异常
当promise通过set_value或set_exception设置结果后,共享状态变为就绪状态,此时所有等待该结果的future都会收到通知。这种机制完美解决了生产者-消费者模型中的同步问题。
关键特性:promise对象是"一次性"的,每个promise只能设置一次值。重复设置将抛出std::future_error异常,错误码为promise_already_satisfied。
1.2 模板特化形式
std::promise提供三种模板形式:
cpp复制template<class R> class promise; // (1) 基础模板
template<class R> class promise<R&>; // (2) 引用特化
template<> class promise<void>; // (3) void特化
其中void特化常用于单纯的线程同步场景,不需要传递具体数值。引用特化则允许传递左值引用,避免大数据拷贝。
2. 核心接口深度剖析
2.1 构造函数与析构
promise的构造函数相对简单,但需要注意其析构行为:
cpp复制std::promise<int> p1; // 默认构造
std::promise<int> p2(std::allocator_arg, alloc); // 带分配器的构造
// 析构时若共享状态未就绪且是最后一个引用,
// 会自动存储broken_promise异常
当promise析构时,如果共享状态未就绪且没有其他引用,会自动存储一个std::future_error异常,错误码为broken_promise。这一机制确保了关联的future不会永久阻塞。
2.2 关键方法解析
2.2.1 get_future()
cpp复制std::future<int> fut = p1.get_future();
该方法返回与promise关联的future对象,有几点需要注意:
- 每个promise只能调用一次get_future(),重复调用抛出future_error
- future和promise共享同一个共享状态
- future对象可以安全地跨线程传递
2.2.2 结果设置方法组
cpp复制p1.set_value(42); // 设置值
p1.set_exception(std::make_exception_ptr(std::runtime_error("error"))); // 设置异常
p1.set_value_at_thread_exit(42); // 线程退出时设置值
p1.set_exception_at_thread_exit(...); // 线程退出时设置异常
s
