第2节:promise介绍

第2节:promise介绍

一、std::promise 介绍

std::promise是C++11 并发编程中常用的一个类,常配合std::future使用。其作用是在一个线程t1 中保存一个类型typename T的值,可供相绑定的std::future对象在另一个线程t2中使用。

用 [futures.state] 的话来说,astd::future是 异步返回对象
(“从共享状态读取结果的对象”),astd::promise是 异步提供者 (“向共享状态提供结果的对象”),即 a promise 是你 设置
结果的东西,这样你就可以从相关的未来中 得到它。

异步提供者最初是创建未来引用的共享状态。std::promise是一种异步提供程序,std::packaged_task是另一种,内部细节std::async是另一种。它们中的每一个都可以创建一个共享状态并为您提供一个std::future共享该状态的对象,并且可以使该状态准备就绪。

std::async是一个更高级别的便利实用程序,它为您提供异步结果对象,并在内部负责创建异步提供程序并在任务完成时使共享状态就绪。std::packaged_task您可以使用
a (或std::bind和 a std::promise)和
a来模拟它,std::thread但它更安全且更易于使用std::async。

std::promise有点低级,因为当您想将异步结果传递给未来时,但使结果准备就绪的代码不能包装在适合传递给的单个函数中std::async。例如,您可能有一个包含多个promises
和关联futures 的数组,并且有一个线程执行多个计算并在每个 promise
上设置一个结果。async只会让你返回一个结果,返回几个你需要async多次调用,这可能会浪费资源。

定义于头文件

<future>
template< class R > class promise; //空模板
template< class R > class promise<R&>; //非 void 特化,用于在线程间交流对象
template<>          class promise<void>;//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<R>::promise
promise(); 

//默认构造函数,构造一个共享状态为空的 std::promise ;

template< class Alloc >  promise( std::allocator_arg_t, const Alloc& alloc );

//构造一个共享状态为空的 std::promise,由 alloc 分配共享状态, Alloc 必须满足分配器 (Allocator) 的要求;参数: alloc - 分配器,用于分配共享状态

promise( promise&& other ) noexcept;

//移动构造函数,用原属 other 的共享状态构造新的 std::promise 对象,使用移动语义。构造完毕后, other 无共享状态;
参数: other - 另一 std::promise 对象,作为获得共享状态的来源。

promise( const promise& other ) = delete;

//std::promise 不可复制。

析构函数
std::promise<R>::~promise
~promise();

抛弃共享状态:
若共享状态就绪,则释放它。
若共享状态未就绪,则存储以 std::future_errc::broken_promise 为 error_condition 的 std::future_error 类型异常对象,令共享状态就绪再释放它。


#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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值