C++11 多线程 future/promise简介

2023-05-16

1. < future >头文件简介

  • Classes
    std::future
    std::future_error
    std::packaged_task
    std::promise
    std::shared_future
  • Functions
    std::async
    std::future_category

2. std::future

简单来说,std::future提供了一种访问异步操作结果的机制。

从字面意思看,它表示未来。通常一个异步操作我们是不能马上就获取操作结果的,只能在未来某个时候获取。我们可以以同步等待的方式来获取结果,可以通过查询future的状态(future_status)来获取异步操作的结果。future_status有三种状态:
deferred:异步操作还没开始
ready:异步操作已经完成
timeout:异步操作超时

获取future结果有三种方式:get、wait、wait_for,其中get等待异步操作结束并返回结果,wait只是等待异步操作完成,没有返回值,wait_for是超时等待返回结果。

例子:

    //查询future的状态
    std::future_status status;
    do {
        status = future.wait_for(std::chrono::seconds(1));
        if (status == std::future_status::deferred) {
            std::cout << "deferred\n";
        } else if (status == std::future_status::timeout) {
            std::cout << "timeout\n";
        } else if (status == std::future_status::ready) {
            std::cout << "ready!\n";
        }
    } while (status != std::future_status::ready);

3. std::promise

Promise对象可保存T类型的值,该值可被future对象读取(可能在另一个线程中),这是promise提供同步的一种手段。在构造promise时,promise对象可以与共享状态关联起来,这个共享状态可以存储一个T类型或者一个由std::exception派生出的类的值,并可以通过get_future来获取与promise对象关联的对象,调用该函数之后,两个对象共享相同的共享状态(shared state)。
Promise对象是异步provider,它可以在某一时刻设置共享状态的值。
Future对象可以返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标识变为ready,然后才能获取共享状态的值。

例子:

#include <iostream>       // std::cout
#include <functional>     // std::ref
#include <thread>         // std::thread
#include <future>         // std::promise, std::future

void print_int(std::future<int>& fut) {
    int x = fut.get(); // 获取共享状态的值.
    std::cout << "value: " << x << '\n'; // 打印 value: 10.
}

int main ()
{
    std::promise<int> prom; // 生成一个 std::promise<int> 对象.
    std::future<int> fut = prom.get_future(); // 和 future 关联.
    std::thread t(print_int, std::ref(fut)); // 将 future 交给另外一个线程t.
    prom.set_value(10); // 设置共享状态的值, 此处和线程t保持同步.
    t.join();
    return 0;
}

std::promise 构造函数

构造函数
default (1)promise();
with allocator (2)template promise (allocator_arg_t aa, const Alloc& alloc);
copy [deleted] (3)promise (const promise&) = delete;
move (4)promise (promise&& x) noexcept;
  • 1.默认构造函数,初始化一个空的共享状态。
  • 2.带自定义内存分配器的构造函数,与默认构造函数类似,但是使用自定义分配器来分配共享状态。
  • 3.拷贝构造函数,被禁用。
  • 4.移动构造函数。
    另外,std::promise 的 operator= 没有拷贝语义,即 std::promise 普通的赋值操作被禁用,operator= 只有 move 语义,所以 std::promise 对象是禁止拷贝的。

std::promise 成员函数

std::promise::get_future:返回一个与promise共享状态相关联的future对象
std::promise::set_value:设置共享状态的值,此后promise共享状态标识变为ready
std::promise::set_exception:为promise设置异常,此后promise的共享状态标识变为ready
std::promise::set_value_at_thread_exit:设置共享状态的值,但是不将共享状态的标志设置为 ready,当线程退出时该 promise 对象会自动设置为 ready(注意:该线程已设置promise的值,如果在线程结束之后有其他修改共享状态值的操作,会抛出future_error(promise_already_satisfied)异常)
std::promise::swap:交换 promise 的共享状态

4. std::packaged_task

std::packaged_task包装了一个可调用的目标(如function, lambda expression, bind expression, or another function object),以便异步调用,它和promise在某种程度上有点像,promise保存了一个共享状态的值,而packaged_task保存的是一个函数。

    std::packaged_task<int()> task([](){ return 7; });
    std::thread t1(std::ref(task)); 
    std::future<int> f1 = task.get_future(); 
    auto r1 = f1.get();

5. 小结

Promise,Future 和 Callback常常作为并发编程中一组非阻塞的模型。其中 Future 表示一个可能还没有实际完成的异步任务的【结果】,针对这个结果可以添加 Callback 以便在任务执行成功或失败后做出对应的操作,而 Promise 交由任务执行者,任务执行者通过 Promise 可以标记任务完成或者失败。

6. std::async

std::async大概的工作过程:先将异步操作用std::packaged_task包装起来,然后将异步操作的结果放到std::promise中,这个过程就是创造未来的过程。外面再通过future.get/wait来获取这个未来的结果。

可以说,std::async帮我们将std::future、std::promise和std::packaged_task三者结合了起来。

std::async的原型:

async(std::launch::async | std::launch::deferred, f, args...)

第一个参数是线程的创建策略,默认的策略是立即创建线程:

std::launch::async:在调用async就开始创建线程。
std::launch::deferred:延迟加载方式创建线程。调用async时不创建线程,直到调用了future的get或者wait时才创建线程。
第二个参数是线程函数,后面的参数是线程函数的参数。

简单的例子:

    std::future<int> f1 = std::async(std::launch::async, [](){ 
        return 8;  
    }); 

    cout<<f1.get()<<endl; //output: 8

    std::future<int> f2 = std::async(std::launch::async, [](){ 
        cout<<8<<endl;
    }); 

    f2.wait(); //output: 8
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11 多线程 future/promise简介 的相关文章

  • Python实现微信自动回复(机器人版本)

    现在微信使用程度越来越高 xff0c 就想到能不能微信实现像qq似得自动回复功能 在实现的过程中发现 xff0c 图灵机器人也有微信的接口 xff0c 就拿来用了 机器人创建完成后 xff0c 会生成一个APIkey xff0c 用来和程序
  • PPTV面试题——括号消除

    题目 xff1a 给定一个字符串 xff0c 设计一个算法消除其中承兑的括号 xff0c 如果括号不成对 xff0c 提示异常 xff08 error xff09 如 xff08 1 xff0c xff08 2 3 xff09 xff0c
  • reStructuredText(rst)简介+安装+简单说明

    reStructuredText简介 43 安装 43 简单说明 reStructuredText是什么 reStructuredText是扩展名为 rst的纯文本文件 xff0c 含义为 重新构建的文本 xff0c 是python编程语言
  • 【VS Code】"The 'clang-format' command is not available. Please check your clang-format."报错

    文章目录 34 The 39 clang format 39 command is not available 34 报错说明一 安装插件 clang format 二 解决方案三 参考链接 34 The clang format comm
  • 大环境不好,找工作太难?看我历时10天三面阿里,成功入职...

    三面大概九十分钟 xff0c 问的东西很全面 xff0c 需要做充足准备 xff0c 就是除了概念以外问的有点懵逼了 xff08 呜呜呜 xff09 回来之后把这些题目做了一个分类并整理出答案 xff08 强迫症的我狂补知识 xff09 分
  • Ubuntu18.04 远程命令行下安装并启动x11vnc

    最近做项目需要连接ubuntu的图像界面 xff0c 开始用XQuartZ xff0c 界面太low太丑 xff0c 而且有些应用启动不了 xff1b 后来转到使用x11vnc xff0c 在网络上查看了很多交安装x11vnc的方法 xff
  • CMakeLists.txt编写常用命令

    文章目录 一 设置cmake最小版本二 设置项目名称三 设置编译目标类型四 指定编译包含的源文件1 明确指明包含的源文件2 搜索指定目录的所有的cpp文件3 自定义搜索规则4 包含多个文件夹里的文件 五 设置包含目录六 设置链接库搜索目录七
  • Docker 拉取镜像及标签 pull | tag

    Docker 拉取镜像及标签 pull tag 重翻Fabric项目的源码 xff0c 发现Docker部分内容 xff0c 有很多不尽理解的地方 xff0c 看着看着 xff0c 就看到使用docker pull拉取Fabric镜像及使用
  • USB大容量存储设备无法启动该怎么办?

    USB大容量存储设备 xff08 USB mass storage device class xff0c 也称为USB MSC或UMS xff09 是一个协议 xff0c 允许一个USB接口的设备与电脑相连接 xff0c 以便在两者之间传输
  • Tensor数据相关的运算、函数讲解及与numpy区别

    Tensor tensorflow 中使用它来表示数据 可以看做多维数组或者list 标量是张量 xff0c 向量是张量 xff0c 矩阵是张量 xff0c 矩阵的矩阵是张量 常用几种定义方法 1 variable变量 xff0c 一般是可
  • QGC4.1.2二次开发(1)--Qt5.12.6 andorid开发环境搭建

    开发环境介绍 xff1a QGC版本 xff1a 4 1 2 Qt版本 xff1a 5 12 6 xff08 QGC要求 xff09 windows平台开发 xff1a vs2017 andorid平台 xff1a JDK Java SE
  • SITL--仿真多架无人机

    SITL仿真环境搭建 ardupliot源码下载与编译 首先需要安装Ardupliot开源飞控的开发环境 xff0c 参考这个知乎博主的文章 xff1a 链接 我的安装环境 ubuntu20 04 先下载Ardupilot源码 xff0c
  • QGC4.1.2二次开发(2)QGC连接与数据收发

    文章目录 前言一 连接原理二 连接过程与数据收发1 连接过程 xff08 以串口为例 xff09 2 数据发送 总结 前言 QGC连接无人机飞控时支持多种连接方式 xff0c 并且可以自动连接 xff0c 不由让人好奇它的实现原理 xff0
  • GRPC远程调用

    目录 FAQ gRPC1 gRPC原理 1 1 什么是RPC 1 2 gRPC的一些特性 1 3 gRPC支持的编程语言 1 4 gRPC的使用场景 1 5 谁在使用gRPC 1 6 gRPC设计之初的动机和原则 2 数据封装和数据传输问题
  • 算法导论->算法基础->2.1插入排序 (从小到大)

    1 伪代码 2 执行过程图 3 c语言实现完整代码 include lt stdio h gt include lt malloc h gt typedef struct MyArray int pbase int length MyArr
  • hihocoder图像算子(高斯消元)

    描述 在图像处理的技术中 xff0c 经常会用到算子与图像进行卷积运算 xff0c 从而达到平滑图像或是查找边界的效果 假设原图为H W的矩阵A xff0c 算子矩阵为D D的矩阵Op xff0c 则处理后的矩阵B大小为 H D 43 1
  • subs()函数()

    摘自matlab Utilities for obsolete MUTOOLS commands subs 既是目录也是函数 subs Symbolic substitution subs S OLD NEW replaces OLD wi
  • IEEE802

    IEEE 官方最新标准 xff1a Browse Standards Get Program IEEE Xplore https ieeexplore ieee org browse standards get program page s
  • 笔记本电脑3C认证要求的相关介绍

    作为CCC强制目录中的产品 xff0c 便携式计算机如果想在国内销售 xff0c 是必须要进行3C认证的 便携式计算机是什么 也就是笔记本电脑 xff0c 平板电脑等 官方的定义是以便携性为特点 xff0c 内置了输入输出设备 电池模块的微
  • 普通门禁卡及各类复制卡相关知识

    转自 xff1a https nfctool cn 42 本文带你了解M1卡的数据结构 xff0c 为以后的破解提供理论基础 同时带你了解各种IC卡 xff0c 让你对破解和复制有更清晰的目标 请注意 xff0c ID卡没有密码 xff0c

随机推荐

  • 用XDS510-V4专业版仿真器连接CCS3.3与28335问题记录

    今天用仿真器连接28335一直没连上 xff0c 错误有 xff1a 1 xff0c 断开仿真器用ccs3 3连接的时候显示为 xff08 不接仿真器 xff0c 空连接 xff09 Error connecting to the targ
  • NVIDIA Jetson TX2 通过vnc 桌面控制

    1 安装Xrdp Windows远程桌面使用的是RDP协议 xff0c 所以ubuntu上就要先安装Xrdp xff0c 在ubuntu软件中心搜索xrdp安装 安装xrdp的同时会自动安装vnc4server xbase clients组
  • NVIDIA Jetson TX2 查看系统参数状态

    1 xff0c 查看Jetson TX2 L4T版本 xff1a head n 1 etc nv tegra release 在刷 JetPack 3 0之前 和刷之后 版本参数发生细微的变化 xff1a REVISION xff1a 由
  • 解决 ImportError: No module named 'serial' 问题

    在pycharm里编写Python串口程序的时候 xff0c 编译时提示 ImportError No module named 39 serial 39 解决办法 xff1a 安装 serial module 这里区分python2和 p
  • 查看ubuntu下Qt的版本

    1 xff0c 查看ubuntu下Qt的版本 打开命令行输入 xff1a span style font size 14px qmake v span
  • 运算放大器基本运算

    转自 xff1a http www 21ic com jichuzhishi analog amplifier 2014 11 11 606654 html 运算放大器组成的电路五花八门 xff0c 令人眼花瞭乱 xff0c 是模拟电路中学
  • KEIL 注解和去注解 快捷键添加

    KEIL 注解和去注解 快捷键添加方法 xff1a 菜单栏Edit gt Configuration gt Shortcut Keys 1 例如设置 注解快捷键 xff1a Ctrl 43 2 例如设置 去注解快捷键 xff1a Ctrl
  • git、vscode免密登录

    1 git配置 git config global list 查看当前配置 git config global user name 34 xiaoyaozi 34 git config global user name 34 xiaoyao
  • 555 单稳态电路

    555 定时器成本低 xff0c 性能可靠 xff0c 只需要外接几个电阻 电容 xff0c 就可以实现多谐振荡器 单稳态 触发器及施密特触发器等脉冲产生与变换电路 它内部包括两个电压比较器 xff0c 三个5K欧姆的等值串联分压电阻 xf
  • Allegro 铺铜设置

    软件版本 xff1a Allegro16 6 敷铜 xff1a 放置禁止敷铜区域 xff1a Setup Areas Route Keepout 1 标题栏选Shap gt Global Dynamic Params Shape Polyg
  • OVP 过压保护电路

    过压保护电路 OVP 为下游电路提供保护 xff0c 使其免受过高电压的损坏 OVP电路监测外部电源 如 xff1a 离线电源或电池 的直流电压 xff0c 通过下述两种方式中的一种保护后续电路 xff1a 撬棍钳位电路或串联开关 撬棍电路
  • 超全蓝牙芯片原厂总结(含芯片型号)

    转自 xff1a https blog csdn net weixin 42583147 article details 80923946 作者 xff1a XCODER 蓝牙芯片原厂 1 CSR 高通 xff08 被高通收购 xff09
  • ST-Link的internal command error问题的解决方法

    问题 xff1a 显示 xff1a internal command error 这是由于stlink无法识别到芯片的情况 xff0c 通过解决这个问题我找到几个原因和解决方法 xff1a 1 xff0c 芯片睡眠 xff0c 停机 xff
  • 蓝牙 UUID 解释

    一 xff0c 什么是 UUID UUID 可以简单理解为编号 xff0c 唯一的编号 xff0c 用于区分不同的个体 服务和特性都有各自的UUID 比如经典的9527 UUID 就跟身份证一样 xff0c 不管是你是局长还是科长 xff0
  • 【人工智能】传教士和野人问题(M-C问题)

    摘要 本题需要解决的是一般情况下的传教士和野人问题 xff08 M C问题 xff09 通过对问题的一般化 xff0c 我们用一个三元组定义了问题的状态空间 xff0c 并根据约束条件制定了一系列的操作规则 xff0c 最后通过两个启发式函
  • 【算法设计与数据结构】为何程序员喜欢将INF设置为0x3f3f3f3f?

    在算法竞赛中 xff0c 我们常常需要用到一个 无穷大 的值 xff0c 对于我来说 xff0c 大多数时间我会根据具体问题取一个99999999之类的数 xff08 显得很不专业啊 xff01 xff09 在网上看别人代码的时候 xff0
  • 【slighttpd】基于lighttpd架构的Server项目实战(7)—http-parser

    对于http服务器 xff0c http request的解析是比较麻烦的 xff0c 由于我们的重点并不在这上面 xff0c 所以这一部分不打算自己编写 xff0c 而是使用开源的http parser库 xff0c 下面我们将使用该库来
  • select和epoll 原理概述&优缺点比较

    这个问题在面试跟网络编程相关的岗位的时候基本都会被问到 xff0c 刚刚看到一个很好的比喻 xff1a 就像收本子的班长 xff0c 以前得一个个学生地去问有没有本子 xff0c 如果没有 xff0c 它还得等待一段时间而后又继续问 xff
  • 笔记-关于神经网络黑盒模型可解释性,可视化

    原博地址 xff1a 深度学习黑盒可视化指南 xff0c 从隐藏层开始 摘 xff1a 一旦神经网络接收到相当大的所需数据集后 xff0c 该网络就会使用其精确的知识 权重 来证明或识别未知数据样本上的模式 即在经过大量数据集训练以后 xf
  • C++11 多线程 future/promise简介

    1 lt future gt 头文件简介 Classes std future std future error std packaged task std promise std shared futureFunctions std as