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

于是接下来要谈的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. vc mfc listctrl使用虚拟列表 虚拟列表用法

    note 虚拟列表可有效加载大量数据 需要处理listctrl的 LVN_GETDISPINFO 消息 使用虚拟列表 不能 使用 insert的方法插入数据,而是告诉listctrl 当前要显示多少行 ...

  2. 【九度OJ】题目1065:输出梯形 解题报告

    [九度OJ]题目1065:输出梯形 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1065 题目描述: 每组测试 ...

  3. spoj-SUBSUMS - Subset Sums

    SUBSUMS - Subset Sums Given a sequence of N (1 ≤ N ≤ 34) numbers S1, ..., SN (-20,000,000 ≤ Si ≤ 20, ...

  4. Beautiful Walls

    [1553] Beautiful Walls 时间限制: 1000 ms 内存限制: 65535 K 问题描述 To simplify the building process, XadillaX b ...

  5. Docker 与 K8S学习笔记(三)—— 镜像的使用

    前面的文章介绍过镜像的三种获取方式: 下载并使用别人创建好的镜像: 在现有镜像上创建新的镜像: 从无到有创建镜像. 本文主要介绍前两种. 一.下载镜像 在Docker Hub上有大量优质镜像可以使用, ...

  6. 51Nod 1264:线段相交(计算几何)

    51Nod 1264:线段相交 Decision 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交). 如果相交,输出"Yes",否则输出&q ...

  7. 【机器学*】k*邻算法-03

    心得体会: 需要思考如何将现实对象转化为特征向量,设置特征向量时记住鸭子定律1 鸭子定律1 如果走路像鸭子.说话像鸭子.长得像鸭子.啄食也像鸭子,那它肯定就是一只鸭子 事物的外在特征就是事物本质的表现 ...

  8. 第七个知识点:随机性如何辅助计算和什么是BPP类问题

    第七个知识点:随机性如何辅助计算和什么是BPP类问题 原文地址:http://bristolcrypto.blogspot.com/2014/11/52-things-number-7-how-doe ...

  9. HTML5 纯CSS3实现正方体旋转3D效果

    实现效果: 实现代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...

  10. C# 后台发送get,post请求及WebApi接收

    后台发送get请求 1.发送带参数的get请求 /// <summary> /// 发送get请求 参数拼接在url后面 /// </summary> /// <para ...