C++11异步操作

C++11异步操作

C++ 11 提供了异步操作相关的类,主要有std::future std::promise std::package_task

std::future作为异步结果的传输通道,获取线程函数的返回值;

std::promise用来包装一个值,将数据和std::future绑定;

std::package用来包装一个对象,将数据和future绑定起来,以方便异步调用;

std::future

future提供了异步查询的通道,我们可以用同步等待的方式来获取结果,可以通过查询future的状态(future_status)来获取异步操作的结果

enum class future_status {ready,   //异步操作已经完成timeout, //异步操作超时deferred //异步操作还没开始
};

image-20210722170858755

我们可以不断查询future的状态,并比对,直到任务完成为止

std::promise

std::promise将数据和future绑定,为获取线程中的某个值提供便利

  1. 在线程函数中为promise赋值
  2. 在线程函数执行完毕后就可以通过promisefuture获取值

示例:

#include<iostream>
#include <string>
#include <tuple>
#include <mutex>
#include <thread>
#include <list>
#include <condition_variable>
#include <future>
using namespace std;
std::promise<int> pr;void set_value(int i)
{std::this_thread::sleep_for(std::chrono::seconds(3));pr.set_value_at_thread_exit(i);
}int main()
{std::thread t1(set_value, 90);t1.join();std::future<int> f = pr.get_future();cout << f.get() << endl;
}

std::package_task

std::package_task包装了一个可调用对象的包装类(function ,lambda function ,bind expression…)

将函数和future绑定起来,以便异步调用

示例:

#include<iostream>
#include <string>
#include <tuple>
#include <mutex>
#include <thread>
#include <list>
#include <condition_variable>
#include <future>
#include <functional>
using namespace std;int return_value(int i )
{cout << i << endl;return i * 10;
}
int main()
{std::packaged_task<int(int)> task(return_value);std::future<int> f = task.get_future();std::thread t(std::ref(task),4);t.join();int result = f.get();cout << result << endl;	
}

std::future``std::promise``std::package_task之间区别

std::future提供了一个访问异步操作结果的机制,它和线程是一个级别的,属于低层次的对象。在std::future之上的高一层是std:packaged_taskstd::promise,它们内部都有future 以便访问异步操作结果,std::packaged_task包装的是一个异步操作,而std:;promise包装的是一个值,都是为了方便异步操作,因为有时需要获取线程中的某个值,这时就用std:promise,而有时需要获一个异步操作的返回值,这时就用std:packaged_task。那么std:promisestd:packaged_task之间又是什么关系呢?可以将一个异步操作的结果保存到std::promise中。futurepromisepackage_task用来作为异步操作或者异步结果的连接通道,用std::futurestd:.shared_future来获取异步调用的结果。future是不可拷贝的,只能移动,shared_future是可以拷贝的,当需要将future放到容器中则需要用shared_future,
package_taskshared_future的基本用法如下:

#include<iostream>
#include <string>
#include <tuple>
#include <mutex>
#include <thread>
#include <list>#include <condition_variable>
#include <future>
#include <functional>
using namespace std;int func(int x)
{return x + 1;
}int main()
{std::packaged_task<int(int)> task(func);std::future<int> fut = task.get_future();std::thread(std::move(task), 2).detach();int value = fut.get();cout << value << endl;vector<std::shared_future<int >> v;std::shared_future<int> f = std::async(std::launch::async, [](int a, int b) {return a + b; }, 2, 3);v.push_back(f);std::cout << v[0].get() << endl;}

有点绕啊…

std::async

std::async可以直接用来创建异步的task,异步操作结果也保存在future中,获取结果时future.get(),

如果不关注异步任务的结果,只是简单地等待任务完成,则调用future.wait()方法

image-20210722182207364

第一个参数f是创建线程的策略

  • std::launch::async:在调用async时就开始创建线程
  • std::launch::deferred:延迟方式创建线程.调用async时不创建线程,调用future函数的get()或者wait()时才创建

image-20210722182915789

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美国Palmbeach大学服务器整合改造案例

位于美国佛罗里达州的palmbeach大学&#xff0c;有4万9千多在校学生和2000多名教工。据学校的信息主管t parziale介绍&#xff0c;目前学校正在进行一个投资160多万美元的关于信息中心服务器、存储、网络等3部分整合改造并简化管理的项目。 该项目主要改造内容是&#xff1a;用…

Enterprise Library 2.0 Hands On Lab 翻译(3):数据访问程序块(三)

练习3&#xff1a;加密数据库连接信息通过该练习&#xff0c;你将学会如何去加密数据库连接信息。第一步打开DataEx3.sln项目&#xff0c;默认的安装路径应该为C:\Program Files\Microsoft Enterprise Library January 2006\labs\cs\Data Access\exercises\ex03\begin&#xff…

操作系统进程学习(Linux 内核学习笔记)

操作系统进程学习(Linux 内核学习笔记) 进程优先级 并非所有进程都具有相同的重要性。除了大多数我们所熟悉的进程优先级之外&#xff0c;进程还有不同的关键度类别&#xff0c;以满足不同需求。首先进程比较粗糙的划分&#xff0c;进程可以分为实时进程 和非实时进程&#x…

【Linux内核】虚拟地址空间布局架构

虚拟地址空间布局架构(Linux内核学习) 1.Linux内核整体架构及子系统 内核对下管理硬件,对上通过运行时库对应用提供服务 用户空间 使用malloc()分配内存通过free()释放内存 内核空间 虚拟进程负责从进程的虚拟地址空间分配虚拟页,sys_brk来扩大或收缩堆,sys_mmap负责在内存映…

【Linux内核】内存映射原理

【Linux内核】内存映射原理 物理地址空间 物理地址是处理器在总线上能看到的地址,使用RISC(Reduced Instruction Set Computing精简指令集)的处理器通常只实现一个物理地址空间,外围设备和物理内存使用统一的物理空间, 有些架构的处理器把分配给外围设备的物理地址称为设备内存…

javascript学习系列(1):数组中的map方法

最好的种树是十年前,其次是现在。歌谣 每天一个前端小知识 提醒你改好好学习了 知乎博主 csdn博主 b站博主 放弃很容易但是坚持一定很酷 我是歌谣 喜欢就一键三连咯 你得点赞是对歌谣最大的鼓励 1前言 在我们的日常开发中 不免会有很多需要处理数据的方法 本节主要说一说m…

【Linux内核】物理内存组织结构

【Linux内核】物理内存组织结构 系统调用mmap 物理内存组织结构 体系结构 目前多处理器系统有两种体系结构&#xff1a; 1&#xff09;非一致内存访问&#xff08;Non-Unit Memory Access&#xff0c;NUMA&#xff09;&#xff1a;指内存被划分成多个 内存节点的多处理器系…

脱离 Rails 看 Ruby

在开始这篇文章之前&#xff0c;我需要澄清一些事情。首先&#xff0c;这不是一篇关于 Ruby on Rails 的文章。如果您希望了解 Rails&#xff0c;每周&#xff08;甚至每小时&#xff09;都有相关的文章和 blog 出现&#xff0c;它们都对这个令人兴奋的框架的众多特性大加推崇&…

如何方便的让你的集合引发改变事件

在我们开发自定义控件的过程中,我们常常会给控件添加集合属性。比如定制Grid控件就会有Column集合。当集合属性发生变化时&#xff0c;比如添加新元素&#xff0c;删除新元素&#xff0c;我们要通知控件去重绘以反映新的变化。我们可以创建一个集合类&#xff0c;在类里添加一个…

[汇编语言]-第八章 div指令,伪指令dd,dup

1- div除法指令 (1) 除数: 有8位和16位两种,在一个寄存器或内存单元中. (2) 被除数: 默认放在AX和DX或AX中 除数为8位, 被除数为16位, 默认在AX中存放. 除数为16位, 被除数为32位, 在DX或AX中存放. AX存放低16位,DX存放高16位. (3) 结果 除数为8位, 则AL存储除法操作的商, AH存…

lambda表达式浅析【C++学习笔记】

lambda表达式浅析【C学习笔记】 基本用法: auto f [/*捕获列表*/](/*参数*/)->int /*后置返回值类型*/{/** 函数体*/};捕获列表: [] : 不捕获任何变量 [变量名] : 表示值捕获,不可修改 [] :按值捕获所有变量,不可修改 [&] : 按引用捕获可以修改 [this] : 在类中捕…

【Cocos2d-x for WP8 学习整理】(2)Cocos2d-Html5 游戏 《Fruit Attack》 WP8移植版 开源...

【Cocos2d-x for WP8 学习整理】&#xff08;2&#xff09;Cocos2d-Html5 游戏 《Fruit Attack》 WP8移植版 开源 原文:【Cocos2d-x for WP8 学习整理】&#xff08;2&#xff09;Cocos2d-Html5 游戏 《Fruit Attack》 WP8移植版 开源这一阵花了些时间&#xff0c;把 cocos2d-h…