如果有两个线程,其中一个线程想要获取另一个线程的返回值,该怎么办?

于是接下来要谈的package_task就是为了解决这个问题而诞生的。

// ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<random>
#include<iostream>
#include<vector>
#include<thread>
#include<algorithm>
#include<future>
using namespace std;
int mythread_one()
{
cout << "子线程1开始执行了,id:" << this_thread::get_id() << endl;
cout << "子线程1执行任务中...." << endl;
this_thread::sleep_for(chrono::seconds(3));
cout << "子线程1任务结束了" << endl;
return 5;
} void mythread_two(future<int> &ps)
{
cout << "子线程2开始执行了" << endl;
auto x = ps.get();
cout << "获取子线程1的值为:" << x << endl;
cout << "子线程2任务执行结束" << endl;
}
int main()
{
//首先用pack_task包裹线程
packaged_task<int(void)> tp(mythread_one);
//通过包裹的对象获取到future对象
future<int> a = tp.get_future();
//创建线程 thread th_one(ref(tp));
//让线程先执行起来
th_one.join(); thread th_two(mythread_two,ref(a));
th_two.join(); return 0;
}

如果有多个线程,都想要获得该值,用这个函数可以做到吗?

下面看截取的这段代码:
void mythread_two(future<int> &ps)
{
cout << "子线程2开始执行了" << endl;
auto x = ps.get();
cout << "获取子线程1的值为:" << x << endl;
cout << "子线程2任务执行结束" << endl;
}

如果变为如下:

void mythread_two(future<int> &ps)
{
cout << "子线程2开始执行了" << endl;
auto x = ps.get();
auto x = ps.get();
cout << "获取子线程1的值为:" << x << endl;
cout << "子线程2任务执行结束" << endl;
}

多加了一行get()语句,经过程序运行是会抛异常的。

解释:get()函数内部实现是移动的语义,也就是说第一次调用后,里面的值已经被移动走了,如果再次调用get()的话,里面的值就为空了。

那该如何解决多线程同时想要获取一个线程资源的方法呢?于是share_future就出现了,下面把代码进行变换:

// ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<random>
#include<iostream>
#include<vector>
#include<thread>
#include<algorithm>
#include<future>
using namespace std;
int mythread_one()
{
cout << "子线程1开始执行了,id:" << this_thread::get_id() << endl;
cout << "子线程1执行任务中...." << endl;
this_thread::sleep_for(chrono::seconds(3));
cout << "子线程1任务结束了" << endl;
return 5;
} void mythread_two(shared_future<int> &ps)
{
cout << "子线程2开始执行了" << endl;
auto x = ps.get();
cout << "获取子线程1的值为:" << x << endl;
cout << "子线程2任务执行结束" << endl;
}
void mythread_three(shared_future<int>& ps)
{
cout << "子线程3开始执行了" << endl;
auto x = ps.get();
cout << "获取子线程1的值为:" << x << endl;
cout << "子线程3任务执行结束" << endl;
}
int main()
{
//首先用pack_task包裹线程
packaged_task<int(void)> tp(mythread_one); shared_future<int> a=tp.get_future(); thread th_one(ref(tp));
//让线程先执行起来
th_one.join(); thread th_two(mythread_two,ref(a));
thread th_three(mythread_three, ref(a));
th_two.join();
th_three.join(); return 0;
}

如果用了share_future的话,调用get()就是值拷贝机制了,所以可以多次调用get().

所以即使像下面这样一样ok

void mythread_three(shared_future<int>& ps)
{
cout << "子线程3开始执行了" << endl;
auto x = ps.get();
auto x = ps.get();
auto x = ps.get();
cout << "获取子线程1的值为:" << x << endl;
cout << "子线程3任务执行结束" << endl;
}

C++11之future(二)的更多相关文章

  1. 【阿里聚安全·安全周刊】阿里双11技术十二讲直播预约|AWS S3配置错误曝光NSA陆军机密文件

    关键词:阿里双11技术十二讲直播丨雪人计划丨亚马逊AWS S3配置错误丨2018威胁预测丨MacOS漏洞丨智能风控平台MTEE3丨黑客窃取<权利的游戏>剧本|Android 8.1   本 ...

  2. C++11多线程のfuture,promise,package_task

    一.c++11中可以在调用进程中获取被调进程中的结果,具体用法如下 // threadTest.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" ...

  3. Python for Informatics 第11章 正则表达式二(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.1 正则表达式的字符匹配 ...

  4. python学习笔记11(函数二): 参数的传递、变量的作用域

    一.函数形参和实参的区别 形参全称是形式参数,在用def关键字定义函数时函数名后面括号里的变量称作为形式参数. 实参全称为实际参数,在调用函数时提供的值或者变量称作为实际参数. >>> ...

  5. C++ 11 笔记 (二) : for循环

    首先肯定的是,我不是标题党.. C++11的for循环确实有跟C++98不一样的地方,还是先上代码: , , , , }; for (int x : test_arr) { std::cout < ...

  6. C++11 并发指南二(std::thread 详解)

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...

  7. 11.8 开课二个月零四天 (Jquery取属性值,做全选,去空格)

    1.jquery取复选框的值 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "htt ...

  8. 11.8 开课二个月零四天 (Jquery)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. C++11 并发指南二(std::thread 详解)(转)

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...

随机推荐

  1. AcWing429. 奖学金

    题目: 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金. 期末,每个学生都有3门课的成绩:语文.数学.英语. 先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从 ...

  2. DP? (hdu3944)

    DP? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 128000/128000 K (Java/Others)Total Subm ...

  3. 带你熟悉鸿蒙轻内核Kconfig使用指南

    摘要:本文介绍了Kconfig的基础知识,和鸿蒙轻内核的图形化配置及进阶的使用方法. 本文分享自华为云社区<鸿蒙轻内核Kconfig使用笔记>,作者: zhushy. 1. Kconfig ...

  4. Color Models (RGB, CMY, HSI)

    目录 概 定义 RGB CMY CMYK HSI 相互的转换 RGB <=> CMY CMY <=> CMYK CMY > CMYK CMYK > CMY RGB ...

  5. iGPT and ViT

    目录 概 主要内容 iGPT ViT 代码 Chen M., Radford A., Child R., Wu J., Jun H., Dhariwal P., Luan D., Sutskever ...

  6. Exponential family of distributions

    目录 定义 性质 极大似然估计 最大熵 例子 Bernoulli 指数分布 正态分布 Choi H. I. Lecture 4: Exponential family of distributions ...

  7. Propensity Scores

    目录 基本的概念 重要的结果 应用 Propensity Score Matching Stratification on the Propensity Score Inverse Probabili ...

  8. Java初学者作业——定义一个计算器类, 实现计算器类中加、 减、 乘、 除的运算方法, 每个方法能够接收2个参数。

    返回本章节 返回作业目录 需求说明: 定义一个计算器类, 实现计算器类中加. 减. 乘. 除的运算方法, 每个方法能够接收2个参数. 实现思路: 定义计算器类. 定义计算器类中加.减.乘.除的方法. ...

  9. 编写Java程序,模拟教练员和运动员出国比赛场景,其中运动员包括乒乓球运动员和篮球运动员。教练员包括乒乓球教练和篮球教练。为了方便出国交流,根乒乓球相关的人员都需要学习英语。

    需求说明: 模拟教练员和运动员出国比赛场景,其中运动员包括乒乓球运动员和篮球运动员.教练员包括乒乓球教练和篮球教练.为了方便出国交流,根乒乓球相关的人员都需要学习英语.具体分析如下: (1)共同的属性 ...

  10. SpringBoot集成MyBatis-Plus代码生成器

    1.说明 本文详细介绍Spring Boot集成MyBatis-Plus代码生成器的方法. 基于一个创建好的Spring Boot工程, 执行MyBatis-Plus提供的AutoGenerator代 ...