九、async、future、packaged_task、promise
std::async、std::future创建后台任务并返回值。
希望线程返回一个值。
std::async是个函数模板,用来启动一个异步任务,返回一个std::future对象
异步任务:自动创建一个线程并开始执行对应的线程入口函数,返回一个std::future对象。
这个对象里面就含有线程函数所返回的结果(线程返回的结果),可以通过调用future对象的成员函数get()来获得。
future:也有人称呼future提供了一个访问异步操作结果的机制,意思是这个结果你可能没有办法立马得到,在不久的将来,在现场执行完毕后,你就能拿到这个结果的,可以理解为,future对象会保存一个值,在将来的某个时刻能够拿到。
#include <future>
#include <thread> using namespace std; int mythread(){
cout<<std::this_thread::get_id()<<endl;
std::chrono::milliseconds dura();//定义了5秒
std::this_thread::sleep_for(dura);//休息了5秒
return ;
}
int main(){
cout << "main" << this_thread::get_id() <<endl;
std::future<int> result = std::async(mythread);//创建了一个线程,同thread类似,第一个参数是线程函数,第二个参数是对象引用,第三个之后的是线程函数的参数
cout<<"continue..."<<endl;
int def;
def=;
cout<<result.get()<<endl;//系统执行到这里会卡到这儿等待子线程,等线程返回5后,继续向下走
//只能调用一次,在调用get就会出错
//result.wait();等待线程返回本身不返回结果
cout<<"main over"<<endl;
return ; }
还可以在最前面添加一个参数,该参数类型是std::lunch类型(枚举类型),来达到一些特殊目的;
延迟调用,并且没有创建新线程,是在主线程中调用的线程入口函数
std::launch::deferred:表示线程入口函数调用被延迟到std::future的wait()或者get()函数调用才执行。
如果wait或get没有被调用,那么线程就根本就没执行也没创建。
std::future<int> result = std::async(std::lunch::deferred,mythread);
前面还有一个参数,是默认的std::launch::async,在调用async函数的时候就创建线程了。
std::packaged_task
打包任务,把任务包装起来。
是个类模板,模板参数是各种可调用对象,通过这个函数把这种可调用对象包转起来,方便将来作为线程入口函数来调用
#include <future>
#include <thread> using namespace std; int mythread(int& pt){
cout << pt << endl;
return ;
}
int main(){
//写法一:
std::packaged_task<int(int)> mypt(mythread);//把函数mythread通过packaged_task包装起来,int(int):第一个int表示线程函数返回类型,括号里的int是线程函数的参数类型
std::thread t1(std::ref(mypt),);//线程直接开始执行,第二个参数就是线程入口函数的参数
t1.join();
std::future<int> result = mypt.get_future();
cout<<result.get()<<endl;
return ; //写法二:用lambda表达式
//这个时候,上面的mythread函数就删掉,相当于将线程入口函数定义写到了这个lambda表达式里面了。
std::packaged_task<int(int)> mypt([](int pt){
cout << pt << endl;
return ; })
}
作用是:
可以使用vector<std::packaged_task<int(int)> > mytask;//用一个容器来保存所有线程入口函数对象
怎么往容器里面添加对象?
std::packaged_task<int(int)> mypt(mythread);
mytasks.push_back(std::move(mypt));//move之后,mypt就空了
怎么取出来?
std::packaged_task<int(int)> mypt2;
auto iter = mytasks.begin();//假设此时这个vector里面只有一个对象
myptr2 = std::move(*iter);//移动语义
mytasks.erase(iter);
std::future<int> result = myptr2.get_future();
cout<<result.get()<<endl;
std::promise,类模板
在某个线程中给他赋值,然后可以在其他线程中把这个值取出来用。
void mythread(std::promise<int>& tmp,int calc){
//做一些列复杂操作
int result = calc;//保存结果
tmp.set_value(result);//结果保存到了tmp对象中
return;
}
int main(){
std::promise<int> myprom;//声明一个promise型对象,保存的值类型为int
std::thread t1(mythread,std::ref(myprom),);
t1.join();
//获取结果值
std::future<int> ful = myprom.get_future();
auto result = ful.get();//get只能调用一次
cout<<result<<endl;
}
九、async、future、packaged_task、promise的更多相关文章
- c++多线程基础5(future,async,packaged_task,promise)
以下内容整理自:https://www.cnblogs.com/my_life/articles/5401190.html future 是一个能从其他地方获取到一个值的对象,如果是在不同的线程中,则 ...
- The promises and challenges of std::async task-based parallelism in C++11 C++11 std::async/future/promise
转载 http://eli.thegreenplace.net/2016/the-promises-and-challenges-of-stdasync-task-based-parallelism- ...
- C++之future和promise
future和promise的作用是在不同线程之间传递数据.使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问:而且指针的方式传递的数据是固定的,如果更改数据类型,那么还需要 ...
- Netty 中的异步编程 Future 和 Promise
Netty 中大量 I/O 操作都是异步执行,本篇博文来聊聊 Netty 中的异步编程. Java Future 提供的异步模型 JDK 5 引入了 Future 模式.Future 接口是 Java ...
- Netty 源码解析(三): Netty 的 Future 和 Promise
今天是猿灯塔“365篇原创计划”第三篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源码解析(二): Netty 的 Channel 当前:Ne ...
- Async/Await替代Promise的6个理由
译者按: Node.js的异步编程方式有效提高了应用性能:然而回调地狱却让人望而生畏,Promise让我们告别回调函数,写出更优雅的异步代码:在实践过程中,却发现Promise并不完美:技术进步是无止 ...
- Future与Promise
https://code.csdn.NET/DOC_Scala/chinese_scala_offical_document/file/Futures-and-Promises-cn.md#ancho ...
- 8张图让你一步步看清 async/await 和 promise 的执行顺序
摘要: 面试必问 原文:8张图帮你一步步看清 async/await 和 promise 的执行顺序 作者:ziwei3749 Fundebug经授权转载,版权归原作者所有. 为什么写这篇文章? 说实 ...
- 6个Async/Await完胜Promise的原因
友情提醒:NodeJS自从7.6版开始已经内置了对async/await的支持.如果你还没用过该特性,那么接下来我会给出一系列的原因解释为何你应该立即开始使用它并且会结合示例代码说明. async/a ...
- 8 张图帮你一步步看清 async/await 和 promise 的执行顺序(转)
https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651555491&idx=1&sn=73779f84c289d9 ...
随机推荐
- 软件-JMeter:JMeter 百科
ylbtech-软件-JMeter:JMeter 百科 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到 ...
- 使用 Vagrant 搭建 Kubernetes 本地测试环境
Vagrant 中文资料 参考资料 Kubernetes 需要一个至少包含三个节点的分布式系统.如果想学习 Kubernetes,或只是在本地搭建测试环境,则可以通过 Vagrant 来简单的实现. ...
- 腾讯开源微服务架构 Tars,高性能 RPC 开发框架
腾讯微服务架构 Tars 于今日正式开源. Tars 取名于电影“星际穿越”中的机器人,是支持多语言的高性能 RPC 开发框架和配套一体化的服务治理平台,可以帮助企业或者用户以微服务的方式快速构建稳定 ...
- (转载)STL map与Boost unordered_map的比较
原链接:传送门 今天看到 boost::unordered_map,它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合 ...
- Pikachu漏洞练习平台实验——SQL注入(四)
1.概述 1.1发生原因 SQL注入漏洞,主要是开发人员在构建代码时,没有对输入边界进行安全考虑,导致攻击者可以通过合法的输入点提交一些精心构造的语句,从而欺骗后台数据库对其进行执行,导致数据库信息泄 ...
- MySQL错误信息语言设置为英文
MySQL错误信息语言设置为英文 安装的wamp环境中,mysql的错误提示信息默认不是英语(大概是法语) 这里说下改为英语的过程 第一步 找到以下文件夹,确保里面可以看到各种"国际方言&q ...
- HttpUrlConnection工具类
package com.ligotop.core.utils; import com.ligotop.core.exceptions.BusinessException; import java.io ...
- HTML5+Canvas手机拍摄,本地压缩上传图片
最近在折腾移动站的开发,涉及到了一个手机里面上传图片.于是经过N久的折腾,找到一个插件,用法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
- Linux:使用awk命令获取文本的某一行,某一列
无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点 这里 可以跳转到教程.”. 1.打印文件的第一列( ...
- macos Item2 添加 Shell Integration (ftp传输)
macos系统 的item2软件 的 Shell Integration (ftp传输) 功能强大,无需 安装其他ftp软件,也是为了保证 密码安全 在使用时报错如下(因为本地 ping不通): ...