【C++11并发】future库 笔记

简介

C++11之前,主线程要想获取子线程的返回值,一般都是通过全局变量,或者类似机制。C++11开始为我们提供了一组方法来获取子线程的返回值,并保证其原子性。

头文件

#include <future>

std::promise

在promise中保存了一个值或者异常,可以通过与其关联的 std::future 来获取这个值或者异常。常规用法

promise有两个特化的版本

template< class R > class promise;    // 普通类模板
template< class R > class promise<R&>;    // 引用特化
template<> class promise<void>;    // void特化

promise提供的方法
在这里插入图片描述
构造方法

promise();    // 默认构造方法
template< class Alloc >
promise( std::allocator_arg_t, const Alloc& alloc );    // cppreference上说是基于一个共享状态构造promise,还没有深入研究具体怎么用
promise( promise&& other ) noexcept;    // 移动构造方法
promise( const promise& other ) = delete;    // 删除了拷贝构造方法

析构方法
析构的时机有两个

  • promise内部共享状态为ready时
  • 如果promise的状态没有被设置为ready析构时,会将std::future_error异常保存到共享状态里

和构造方法类似,promise只支持移动赋值操作符

promise& operator=( promise&& other ) noexcept;
promise& operator=( const promise& rhs ) = delete;

获取future,如果get_future是被重复调用的,那么就会抛出std::future_error异常。如果想多个地方获取future,需要使用std::shared_future,他可以通过std::future构造。这是std::shared_future相应的构造方法的声明:shared_future( std::future&& other )

std::future<R> get_future();

设置共享数据,以及将共享状态设置为ready。由于promise有特化版本,下面声明的方法有些版本没有。另外,如果重复调用set_value会抛出std::future_error异常,即set_value只能调用一次。

void set_value( const R& value );    // member only of generic promise template
void set_value( R&& value );     //member only of generic promise template
void set_value( R& value );     // member only of promise<R&> template specialization
void set_value();    // 设置共享状态为ready

设置异常,以及将共享状态设置为ready,例子

void set_exception( std::exception_ptr p );

set_value_at_thread_exit 和 set_exception_at_thread_exit 类似set_value 和 set_exception,不同点是 xx_at_thread_exit 是在线程结束的时候将共享状态设置为ready,而set_xx 是立刻设置为ready。

std::future

future类是获取异步操作返回的封装。promise相当于是set,future相当于是get

类似promise,future也有两个特化版本

template< class T > class future;
template< class T > class future<T&>;
template<> class future<void>;

future提供的方法
在这里插入图片描述
构造方法

future() noexcept;    // 不关联任何共享状态
future( future&& other )     // 移动构造
future( const future& other ) = delete;    // 拷贝构造被删除

只有移动赋值操作符

future& operator=( future&& other ) noexcept;
future& operator=( const future& other ) = delete;

从构造方法和移动赋值操作符可以看出,future是唯一关联共享状态的,如果想多个future关联一个共享状态,future是不行的,需要将其转为std::shared_future。对应的方法是share:

std::shared_future<T> share() noexcept;

share方法内部是这么构造shared_future的:std::shared_future(std::move(*this)),所以调用share方法后,原理的future就不在关联共享状态了,也就不能再调用相关get方法,否则会抛出异常

std::shared_future

和std::future唯一的不同就是,std::shared_future可以多个对象同时关联同一个共享状态。他的特化版本、提供的方法和std::future也基本类似:
在这里插入图片描述

std::packaged_task

将可调用对象(函数,lambda表达式,仿函数等)包装后,可以异步调用,通过std::future获取返回值。参考代码

std::packaged_task 提供的方法
在这里插入图片描述

构造方法

packaged_task() noexcept;

template< class F >
explicit packaged_task( F&& f );    // f为可调用对象,他是一个万能引用,即构造package_task的时候,可以传递给他可调用对象的左值,右值,左值引用,右值引用;参考:https://zhuanlan.zhihu.com/p/99524127

template< class F, class Allocator >
explicit packaged_task( std::allocator_arg_t, const Allocator& a, F&& f );    // C++17删除了该方法

packaged_task( const packaged_task& ) = delete;

packaged_task( packaged_task&& rhs ) noexcept;    // 移动构造方法

析构方法
如果在共享状态设置为ready之前析构package_task,会抛出 std::future_errc::broken_promise 异常

只有移动赋值操作符

packaged_task& operator=( const packaged_task& ) = delete;
packaged_task& operator=( packaged_task&& rhs ) noexcept;

判断package_task对象是否有共享状态,比如用无参的构造方法构造的对象,就没有共享状态

bool valid() const noexcept;

获取future,如果重复调用get_future,会抛出std::future_error异常;另外,如果valid()方法返回为false,调用get_future,也会抛出std::future_error异常

std::future<R> get_future();

执行保存的可调用对象,和get_future一样重复调用,或者pakage_task对象没有共享状态,都会抛出std::future_error异常

void operator()( ArgTypes... args );

在线程结束,局部变量释放后,将共享状态设置为ready。抛出异常的情况和operator()一样

void make_ready_at_thread_exit( ArgTypes... args );

重置package_task的共享状态,等价于 *this = packaged_task(std::move(f)), f 是可调用对象。此时会构造新的共享状态,如果没有足够内存,会抛出std::bad_alloc异常。如果package_task对象没有共享状态,就会抛出std::future_error异常

void reset();

std::async

异步直行一个可调用对象
在这里插入图片描述

enum class launch : /* unspecified */ {
    async =    /* unspecified */,    // 立刻异步直行
    deferred = /* unspecified */,    // 
    /* implementation-defined */
};

当使用launch::deferred时,只有future调用get或者wait方法时,才会异步直行可调用对象

cppreference

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/179666.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

electron27-react-mateos:基于electron+react18仿matePad桌面系统

基于Electron27React18ArcoDesign搭建桌面版OS管理系统。 electron-react-mateos 基于最新前端跨端技术栈electron27.xreact18arco-designzustand4sortablejs构建的一款仿制matePad界面多层级路由管理OS系统。 ElectronReactOS支持桌面多路由配置&#xff0c;新开窗口弹窗开启路…

[Halcon检测] 划痕检测之高斯导数提取

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…

【开源】基于Vue和SpringBoot的大学生相亲网站

项目编号&#xff1a; S 048 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S048&#xff0c;文末获取源码。} 项目编号&#xff1a;S048&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询会员4…

解决Activiti5.22流程图部署在Windows上正常,但在linux上部署后出现中文变方块的问题

总结/朱季谦 楼主最近在做公司的工作流平台&#xff0c;发现一个很无语的事情&#xff0c;Activiti5.22的流程图在Windows环境上部署&#xff0c;是可以正常查看的&#xff0c;但发布到公司的Linux服务器上后&#xff0c;在上面进行流程图在线部署时&#xff0c;发现中文都变成…

人工智能-循环神经网络的简洁实现

循环神经网络的简洁实现 如何使用深度学习框架的高级API提供的函数更有效地实现相同的语言模型。 我们仍然从读取时光机器数据集开始。 import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35…

【开源】基于Vue和SpringBoot的学校热点新闻推送系统

项目编号&#xff1a; S 047 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S047&#xff0c;文末获取源码。} 项目编号&#xff1a;S047&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新…

【深度学习】卷积神经网络(CNN)

一、引子————边界检测 我们来看一个最简单的例子&#xff1a;“边界检测&#xff08;edge detection&#xff09;”&#xff0c;假设我们有这样的一张图片&#xff0c;大小88&#xff1a; 图片中的数字代表该位置的像素值&#xff0c;我们知道&#xff0c;像素值越大&#…

ubuntu上查看各个进程的实时CPUMEM占用的办法

top常见参数top界面分析system monitorhtop1、查看htop的使用说明2、显示树状结构3、htop使用好文推荐top top的用法应该是最为普遍的 常见参数 -d 更新频率,top显示的界面几秒钟更新一次 -n 更新的次数,top显示的界面更新多少次之后就自动结束了 当然也可以将top日志通过…

3分钟使用 WebSocket 搭建属于自己的聊天室(WebSocket 原理、应用解析)

文章目录 WebSocket 的由来WebSocket 是什么WebSocket 优缺点优点缺点 WebSocket 适用场景主流浏览器对 WebSocket 的兼容性WebSocket 通信过程以及原理建立连接具体过程示例Sec-WebSocket-KeySec-WebSocket-Extensions 数据通信数据帧帧头&#xff08;Frame Header&#xff09…

Pandas一键爬取解析代理IP与代理IP池的维护

目录 前言 一、获取代理IP 二、解析代理IP 三、维护代理IP池 四、完整代码 总结 前言 在爬虫过程中&#xff0c;我们经常会使用代理IP来绕过一些限制&#xff0c;比如防止被封IP等问题。而代理IP的获取和维护是一个比较麻烦的问题&#xff0c;需要花费一定的时间和精力。…

机器学习/sklearn 笔记:K-means,kmeans++,MiniBatchKMeans

1 K-means介绍 1.0 方法介绍 KMeans算法通过尝试将样本分成n个方差相等的组来聚类&#xff0c;该算法要求指定群集的数量。它适用于大量样本&#xff0c;并已在许多不同领域的广泛应用领域中使用。KMeans算法将一组样本分成不相交的簇&#xff0c;每个簇由簇中样本的平均值描…

Ocam——自由录屏工具~

当我们想要做一些混剪、恶搞类型的视频时&#xff0c;往往需要源影视作品中的诸多素材&#xff0c;虽然可以通过裁减mp4文件的方式来获取片段&#xff0c;但在高画质的条件下&#xff0c;mp4文件本身通常会非常大&#xff0c;长此以往&#xff0c;会给剪辑工作带来诸多不便&…

使用 PowerShell 创建共享目录

在 Windows 中&#xff0c;可以使用共享目录来将文件和文件夹共享给其他用户或计算机。共享目录可以通过网络访问&#xff0c;这使得它们非常适合用于文件共享、协作和远程访问。 要使用 PowerShell 创建共享目录&#xff0c;可以使用 New-SmbShare cmdlet。New-SmbShare cmdl…

arduino入门一:点亮第一个led

void setup() { pinMode(12, OUTPUT);//12引脚设置为输出模式 } void loop() { digitalWrite(12, HIGH);//设置12引脚为高电平 delay(1000);//延迟1000毫秒&#xff08;1秒&#xff09; digitalWrite(12, LOW);//设置12引脚为低电平 delay(1000); }

聚观早报 |快手Q3营收;拼多多杀入大模型;Redmi K70E开启预约

【聚观365】11月23日消息 快手Q3营收 拼多多杀入大模型 Redmi K70E开启预约 华为nova 12系列或下周发布 亚马逊启动“AI就绪”新计划 快手Q3营收 财报显示&#xff0c;快手第三季度营收279亿元&#xff0c;同比增长20.8%&#xff1b;期内盈利21.8亿元&#xff0c;去年同期…

2023 年 亚太赛 APMCM (A题)国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 完整内容可以在文章末尾领取&#xff01; 问题1 图像处理&am…

免费多域名SSL证书

顾名思义&#xff0c;免费多域名SSL证书就是一种能够为多个域名或子域提供HTTPS安全保护的证书。这意味着&#xff0c;如果您有三个域名——例如example.com、example.cn和company.com&#xff0c;您可以使用一个免费的多域名SSL证书为所有这些域名提供安全保障&#xff0c;而无…

Missing file libarclite_iphoneos.a 问题解决方案

问题 在Xcode 运行项目会报以下错误 File not found: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a解决方案 打开URL https://github.com/kamyarelyasi/Libarclite-Files &#xff0c;下载liba…

解决Android端libc++_shared.so库冲突问题

前言 随着App功能增多&#xff0c;集成的so库也会增多&#xff0c;如果系统中多个so库都使用系统自动生成的libc_shared.so库&#xff0c;如果多个SDK都有该so包&#xff0c;就会出现报错&#xff1a; 解决办法 如果出现该问题&#xff0c;说明您的项目中有多个SDK共同依赖了C标…