C++并发编程之线程异步std::promise知识点总结

1、std::promise介绍

std::promise是一个模板类,其对象可保存T类型的值,该值可以被另外一个线程读取,也就是说可以通过异步的方式读取该值。在定义std::promise时,它是和std::future配合进行使用的,最常用的方式是std::future = std::promise::get_future()。在另外一个线程中通过std::future::get()成员函数得到线程的返回值或者执行结果。当然了,在调用std::future::get()时,如果std::future对象状态不是ready,则调用的地方将一直阻塞等待。

使用std::promise时需要包含的头文件:

#include <future>

首先看下关于std::promise的定义

/// Primary template for promise
  template<typename _Res>
    class promise
    {
      typedef __future_base::_State_base 	_State;
      typedef __future_base::_Result<_Res>	_Res_type;
      typedef __future_base::_Ptr<_Res_type>	_Ptr_type;
      template<typename, typename> friend class _State::_Setter;

      shared_ptr<_State>                        _M_future;
      _Ptr_type                                 _M_storage;

    public:
      promise()
      : _M_future(std::make_shared<_State>()),
	_M_storage(new _Res_type())
      { }

      promise(promise&& __rhs) noexcept
      : _M_future(std::move(__rhs._M_future)),
	_M_storage(std::move(__rhs._M_storage))
      { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator& __a)
        : _M_future(std::allocate_shared<_State>(__a)),
	  _M_storage(__future_base::_S_allocate_result<_Res>(__a))
        { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
        : _M_future(std::move(__rhs._M_future)),
	  _M_storage(std::move(__rhs._M_storage))
        { }

      promise(const promise&) = delete;

      ~promise()
      {
        if (static_cast<bool>(_M_future) && !_M_future.unique())
          _M_future->_M_break_promise(std::move(_M_storage));
      }

      // Assignment
      promise&
      operator=(promise&& __rhs) noexcept
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

      promise& operator=(const promise&) = delete;

      void
      swap(promise& __rhs) noexcept
      {
        _M_future.swap(__rhs._M_future);
        _M_storage.swap(__rhs._M_storage);
      }

      // Retrieving the result
      future<_Res>
      get_future()
      { return future<_Res>(_M_future); }

      // Setting the result
      void
      set_value(const _Res& __r)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(this, __r);
        __future->_M_set_result(std::move(__setter));
      }

      void
      set_value(_Res&& __r)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(this, std::move(__r));
        __future->_M_set_result(std::move(__setter));
      }

      void
      set_exception(exception_ptr __p)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(__p, this);
        __future->_M_set_result(std::move(__setter));
      }
    };

  template<typename _Res>
    inline void
    swap(promise<_Res>& __x, promise<_Res>& __y) noexcept
    { __x.swap(__y); }

  template<typename _Res, typename _Alloc>
    struct uses_allocator<promise<_Res>, _Alloc>
    : public true_type { };


  /// Partial specialization for promise<R&>
  template<typename _Res>
    class promise<_Res&>
    {
      typedef __future_base::_State_base	_State;
      typedef __future_base::_Result<_Res&>	_Res_type;
      typedef __future_base::_Ptr<_Res_type> 	_Ptr_type;
      template<typename, typename> friend class _State::_Setter;

      shared_ptr<_State>                        _M_future;
      _Ptr_type                                 _M_storage;

    public:
      promise()
      : _M_future(std::make_shared<_State>()),
	_M_storage(new _Res_type())
      { }

      promise(promise&& __rhs) noexcept
      : _M_future(std::move(__rhs._M_future)),
	_M_storage(std::move(__rhs._M_storage))
      { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator& __a)
        : _M_future(std::allocate_shared<_State>(__a)),
	  _M_storage(__future_base::_S_allocate_result<_Res&>(__a))
        { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
        : _M_future(std::move(__rhs._M_future)),
	  _M_storage(std::move(__rhs._M_storage))
        { }

      promise(const promise&) = delete;

      ~promise()
      {
        if (static_cast<bool>(_M_future) && !_M_future.unique())
          _M_future->_M_break_promise(std::move(_M_storage));
      }

      // Assignment
      promise&
      operator=(promise&& __rhs) noexcept
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

      promise& operator=(const promise&) = delete;

      void
      swap(promise& __rhs) noexcept
      {
        _M_future.swap(__rhs._M_future);
        _M_storage.swap(__rhs._M_storage);
      }

      // Retrieving the result
      future<_Res&>
      get_future()
      { return future<_Res&>(_M_future); }

      // Setting the result
      void
      set_value(_Res& __r)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(this, __r);
        __future->_M_set_result(std::move(__setter));
      }

      void
      set_exception(exception_ptr __p)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(__p, this);
        __future->_M_set_result(std::move(__setter));
      }
    };

2、std::promise重要的成员函数介绍

在上面的定义中,将比较常用的成员函数给张贴出来,进行一一分析。

void swap(promise& __rhs); //交换promise的状态
future<_Res> get_future(); //产生一个std::future的对象,用以其他线程获得线程的执行结果
void set_value(const _Res& __r);//设置value的值,并且使状态为ready,否则抛出std::future_error
void set_value(_Res&& __r);//设置value的值,并且使状态为ready,或者抛出std::future_error
void set_exception(exception_ptr __p);//设置__p为异常,并使状态为ready,或者抛出std::future_error
void swap(promise<_Res>& __x, promise<_Res>& __y);//交换两个promise的状态

3、std::promise用法示例程序

/*************************************************************************
	> File Name: thread_promise.cpp
	> Author: 小和尚敲木鱼
	> Mail:  
	> Created Time: Tue 21 Sep 2021 03:05:23 AM PDT
 ************************************************************************/

#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <list>
#include <mutex>
#include <future>
#include <chrono>

using namespace std;
/*****************************文件说明***********************************/
int function_1(std::promise<int> &ret_promise,int param)//线程
{
	int ret = 10;
	std::cout << __func__ << " param =" << param  << std::endl;
	std::chrono::milliseconds sleeptime(500);
	std::this_thread::sleep_for(sleeptime);
	std::cout << __func__ << " thread id ="<< std::this_thread::get_id() << std::endl;
	std::cout << __func__ << " return = "<< ret + param << std::endl;
	ret_promise.set_value((ret + param));
}

int main(int agc,char * agv[])
{
	int temp = 20;
	std::cout << "Main thread id =" << std::this_thread::get_id() << std::endl;
	std::promise<int> test_promise;
	std::thread thread1(function_1,std::ref(test_promise),50);
	std::future<int>  fu_test = test_promise.get_future();
	auto result = fu_test.get(); //获得结果,如果fu_test不ready,则一直阻塞。
	std::cout << __func__ << " result = " << result << std::endl;

	if (thread1.joinable())
	{
		thread1.join();
	}
	return 0;
}
//OUT
//Main thread id =139709165758272
//function_1 param =50
//function_1 thread id =139709148403456
//function_1 return = 60
//main result = 60
/**************************end of file**********************************/


4、总结

std::promise用与异步线程得到线程执行的返回结果,在使用中需要注意std::promise是和std::future配合的,这点需要注意。
Todo:
其余细节,后续补充。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给大佬递杯卡布奇诺

你们的鼓励就是我传作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值