C++11获取线程的返回值
来源:互联网 发布:php教程视频教程全集 编辑:程序博客网 时间:2024/06/06 04:12
C++11 std::future
and std::promise
在许多时候,我们会有这样的需求——即我们想要得到线程返回的值。
但是在C++11 多线程中我们注意到,std::thread
对象会忽略顶层函数的返回值。
那问题来了,我们要怎么获得线程的返回值呢?
我们通过一个例子来说明如何实现这个需求。
假设我们的app会创建一个线程来压缩一个文件夹,该线程在压缩完文件夹后会返回压缩文件 *.zip 和这个zip文件的大小,我们现在就想获得这个线程的返回值。
有两种方法可以实现这个需求:
1. 传统的方法:在线程间共享指针
传递一个指针给压缩文件的线程,表示压缩文件的线程将会把值写入指针指向的内存空间。此时主线程将用条件变量等待值被写入,当压缩文件线程把值写入指针指定的内存后,将唤醒(signal)条件变量,然后主线程将被唤醒,然后从指针指向的内存中获取返回值。
为了实现获取一个返回值的需求,使用传统的方法,我们需要条件变量(condition variable), 互斥量(mutex),和指针三个对象。
如果假设,我们需要获得压缩线程里三个返回值,情况会变得更加复杂。
那std::future
就是来简化这个编程过程的
2. C++11的方法:使用std::future
和std::promise
人如其名,std::future
和std::promise
对象就和他们的名字一样。这两个类在获取程序返回值的时候需要配合使用
std::future
,是一个类模板,它存储着一个未来的值。
那问题来了,未来的值是什么鬼?
实际上一个std::future
对象里存储着一个在未来会被赋值的变量,这个变量可以通过std::future
提供的成员函数std::future::get()
来得到。如果在这个变量被赋值之前就有别的线程试图通过std::future::get()
获取这个变量,那么这个线程将会被阻塞到这个变量可以获取为止。
std::promise
同样也是一个类模板,它的对象承诺会在未来设置变量(这个变量也就是std::future
中的变量)。每一个std::promise
对象都有一个与之关联的std::future
对象。当std::promise
设置值的时候,这个值就会赋给std::future
中的对象了。
我们一步一步来看一下如何做
在主线程中创建
std::promise
对象std::promise<int> promiseObj;
上面定义的promise对象还没有任何关联的值。但是它承诺某个线程将会设置与其关联的值,并且,当值被设置以后,可以通过与promise关联的
std::future
对象来获取该值。
假设我们的主线程将创建的std::promise
对象传递给了压缩线程,那主线程要怎么知道压缩线程已经设置好了值呢?
答案就是使用 std::future
对象
// main threadstd::future<int> futureObj = promiseObj.get_future();int val = futureObj.get();// compression threadpromiseObj.set_value(45);
在compression thread未执行set_value()
时,如果主线程调用了futureObj.get()
,那么主线程将会被阻塞。
看整个时序图:
最终代码
#include<iostream> //std::cout std::endl#include<thread> //std::thread#include<future> //std::future std::promise#include<utility> //std::ref#include<chrono> //std::chrono::secondsvoid initiazer(std::promise<int> &promiseObj){ std::cout << "Inside thread: " << std::this_thread::get_id() << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); promiseObj.set_value(35);}int main(){ std::promise<int> promiseObj; std::future<int> futureObj = promiseObj.get_future(); std::thread th(initiazer, std::ref(promiseObj)); std::cout << futureObj.get() << std::endl; th.join(); return 0;}
- C++11获取线程的返回值
- Java 并发:获取线程的返回值
- java获取线程的返回值
- Callable 获取线程返回值
- FutureTask获取线程返回值
- C语言函数返回值的获取
- java有返回值的线程,可以获取线程里面的返回值
- vc中获取一个线程的状态及返回值
- 使用callable获取子线程的返回值
- python threading获取线程函数返回值
- python threading获取线程函数返回值
- afxAfxBeginThread 获取线程函数返回值
- c++builder 多线程-创建 退出 及获取线程返回码
- 基础篇:获取线程返回值与守护线程的创建(二)
- FutureTask获取线程返回值, 用来获取耗时较长的计算结果
- ADO.net 里面获取返回值的方法为(c#):
- c程序shell脚本获取返回值的方法
- C#获取C/C++返回值为wchar_t*的内容
- session
- Intent的用法(1)
- (SSL证书)apache添加https
- 八大排序算法代码C
- 再起航,我的学习笔记之JavaScript设计模式26(解释器模式)
- C++11获取线程的返回值
- nutch和solr做爬虫
- sourceTree 问题解决
- HDU-1001 calculate SUM(n) = 1 + 2 + 3 + ... + n.
- easyui queryParams的使用
- 我是如何利用Hadoop做大规模日志压缩的
- Java分布式爬虫Nutch教程——导入Nutch工程,执行完整爬取
- HDU-1049 Climbing Worm
- 新的选择