IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++并发编程之线程异步std::promise知识点总结 -> 正文阅读

[C++知识库]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:
其余细节,后续补充。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-13 11:17:51  更:2021-10-13 11:18:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:36:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码