走进C++11(二十八) 一诺千金 std::promise

图片

 

promise 对象可以保存某一类型 T 的值,该值可被 future 对象读取(可能在另外一个线程中),因此 promise 也提供了一种线程同步的手段。在 promise 对象构造时可以和一个共享状态(通常是std::future)相关联,并可以在相关联的共享状态(std::future)上保存一个类型为 T 的值。

 

可以通过 get_future 来获取与该 promise 对象相关联的 future 对象,调用该函数之后,两个对象共享相同的共享状态(shared state)

 

promise 对象是异步 Provider,它可以在某一时刻设置共享状态的值。

 

future 对象可以异步返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标志变为 ready,然后才能获取共享状态的值。

 

下面我们来看看官方定义:

 

定义于头文件 <future>  

template< class R > class promise;

(1)(C++11 起)

template< class R > class promise<R&>;

(2)(C++11 起)

template<>          class promise<void>;

(3)(C++11 起)

 

1) 空模板

2) 非 void 特化,用于在线程间交流对象

3) void 特化,用于交流无状态事件

 

类模板 std::promise 提供存储值或异常的设施,之后通过 std::promise 对象所创建的 std::future 对象异步获得结果。注意 std::promise 只应当使用一次。

 

每个 promise 与共享状态关联,共享状态含有一些状态信息和可能仍未求值的结果,它求值为值(可能为 void )或求值为异常。promise 可以对共享状态做三件事:

 

  • 使就绪:promise 存储结果或异常于共享状态。标记共享状态为就绪,并解除阻塞任何等待于与该共享状态关联的 future 上的线程。

  • 释放:promise 放弃其对共享状态的引用。若这是最后一个这种引用,则销毁共享状态。除非这是 std::async 所创建的未就绪的共享状态,否则此操作不阻塞。

  • 抛弃:promise 存储以 std::future_errc::broken_promise 为 error_code 的 std::future_error 类型异常,令共享状态为就绪,然后释放它。

  •  

promise 是 promise-future 交流通道的“推”端:存储值于共享状态的操作同步于(定义于 std::memory_order )任何在共享状态上等待的函数(如 std::future::get )的成功返回。其他情况下对共享状态的共时访问可能冲突:例如, std::shared_future::get 的多个调用方必须全都是只读,或提供外部同步。

 

成员函数

 

(构造函数)

构造std::promise对象
(公开成员函数)

(析构函数)

析构std::promise对象
(公开成员函数)

operator=

赋值共享状态
(公开成员函数)

swap

交换二个 promise 对象
(公开成员函数)

获取结果

get_future

返回与承诺的结果关联的 future
(公开成员函数)

设置结果

set_value

设置结果为指定值
(公开成员函数)

set_value_at_thread_exit

设置结果为指定值,同时仅在线程退出时分发提醒
(公开成员函数)

set_exception

设置结果为指示异常
(公开成员函数)

set_exception_at_thread_exit

设置结果为指示异常,同时仅在线程退出时分发提醒
(公开成员函数)

 

下面举一个小例子,将promise<int> 用作线程间信号:

 

#include <vector>#include <thread>#include <future>#include <numeric>#include <iostream>#include <chrono> void accumulate(std::vector<int>::iterator first,                std::vector<int>::iterator last,                std::promise<int> accumulate_promise){    int sum = std::accumulate(first, last, 0);    accumulate_promise.set_value(sum);  // 提醒 future} void do_work(std::promise<void> barrier){    std::this_thread::sleep_for(std::chrono::seconds(1));    barrier.set_value();} int main(){    // 演示用 promise<int> 在线程间传递结果。    std::vector<int> numbers = { 1, 2, 3, 4, 5, 6 };    std::promise<int> accumulate_promise;    std::future<int> accumulate_future = accumulate_promise.get_future();    std::thread work_thread(accumulate, numbers.begin(), numbers.end(),                            std::move(accumulate_promise));     // future::get() 将等待直至该 future 拥有合法结果并取得它    // 无需在 get() 前调用 wait()    //accumulate_future.wait();  // 等待结果    std::cout << "result=" << accumulate_future.get() << '\n';    work_thread.join();  // wait for thread completion     // 演示用 promise<void> 在线程间对状态发信号    std::promise<void> barrier;    std::future<void> barrier_future = barrier.get_future();    std::thread new_work_thread(do_work, std::move(barrier));    barrier_future.wait();    new_work_thread.join();}

 

输出:

result=21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值