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,一经查实,立即删除!

相关文章

GDI对象的初始化

GDI对象的初始化 一、GR_GraphicsFactory对象的初始化在XAP_App对象的构造函数中创建GR_GraphicsFactory对象。在XAP_Win32App构造函数中&#xff0c;调用GR_GraphicsFactory对象的registerClass函数初始化m_vAllocators、m_vDescriptors、m_vClassIds集合成员变量&#xff0c;…

存储过程从入门到熟练(多个存储过程完整实例及调用方法)_AX

①为什么要使用存储过程?因为它比SQL语句执行快.②存储过程是什么?把一堆SQL语句罗在一起,还可以根据条件执行不通SQL语句.(AX写作本文时观点)③来一个最简单的存储过程CREATE PROCEDURE dbo.testProcedure_AXASselect userID from USERS order by userid desc注:dbo.testPro…

Abiword中字符操作

Abiword中字符操作 一、关于不同字符的宏定义 typedef gunichar UT_UCS4Char;typedef guint16 UT_UCS2Char;typedef UT_UCS4Char UT_UCSChar; /* Unicode */ typedef guint32 gunichar;typedef guint16 gunichar2; AbiWord is now fully converted to using 32-bi…

C++ 11线程池 ThreadPool

线程池 ThreadPool 半同步半异步线程池(简略版)C11实现,详细解析 同步队列 SynchronousQueue.hpp #include <list> #include <mutex> #include <thread> #include <condition_variable> #include <iostream> using namespace std;template&l…

ITPro Magazine2006年第6期发布

下载地址[url]http://www.cnfan.net/magazine/itpromagazine200606.rar[/url]主题企划Windows Fundamentals For Legacy PCs深度解析&#xff1a;Windows Vista RC1的五大特性系统应用Win2003平台php环境架设Xen3安装及使用(On Fedora core5)ISA Server 2004 ***应用网络与安全…

abiword class list

Class List【转自官方文档】 Here are the classes, structs, unions and interfaces with brief descriptions:GR_CharWidths::_a _AbiCellRendererFont _AbiCellRendererFontClass _AbiControlGUI _AbiFontCombo _AbiFontComboClass _AbiPrivData _AbiTable _AbiWidget _AbiW…

网络资源的初始化与释放(C++ RAII惯用法)

1. 网络资源的初始化与释放(C RAII惯用法) C RAII 惯用法 RAII (Resource Acquisition Is Initialization)资源获取即初始化 我们拿到资源的时候就已经初始化,一旦不需要该资源,该资源就会被释放 资源: 在 C 的语境下&#xff0c;资源代表一些可以必须先被获取才能使用的对…

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

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

避免switch嵌套的一种方法

避免switch嵌套的一种方法 DWORD nFlags 0;switch (mouse.nButton){case 0: //左键nFlags 1;case 1: //右键nFlags 2;break;case 2: //中间nFlags 4;break;case 4:nFlags 8;break;}if (nFlags ! 8)SetCursorPos(mouse.ptXY.x, mouse.ptXY.y);switch (mouse.nAction){case…

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…

gcc对C语言的扩展:语句内嵌表达式(statement-embedded expression)

在gnu c 中&#xff0c;用括号将复合语句括起来也形成了表达式。他允许你在一个表达式内使用循环&#xff0c;跳转和局部变量。一个复合语句是用大括号{}括起来的一组语句。在包含语句的表达式这种结构中&#xff0c;再用括号( )将大括号括起来,例如&#xff1a;({ int y foo …

react学习(56)--常见HTTP错误

200: 服务器成功返回请求的数据。,201: 新建或修改数据成功。,202: 一个请求已经进入后台排队&#xff08;异步任务&#xff09;。,204: 删除数据成功。,400: 发出的请求有错误&#xff0c;服务器没有进行新建或修改数据的操作。,401: 用户没有权限&#xff08;令牌、用户名、密…

C#二叉树递归实现

二叉树类(binaryTree.cs) using System; namespace binary_tree_demo { class BinaryTreeNode where T : IComparable { public BinaryTreeNode() { left null; right null; } public BinaryTreeNode(BinaryTreeNode l, BinaryTreeNode r) { left l; right r; } public Bin…

Linux守护进程的创建(结合nginx框架)

Linux守护进程的创建(结合nginx框架) 先介绍几个相关函数: int dup2(arg1,arg2):参数一指向的内容赋给参数二,shi的参数二也能访问参数一所指向的内容,并返回新的描述符 int fork()创建子进程,返回值-1:创建失败 返回值0:子进程 返回其他:父进程 setsid()调用成功后&#x…