C++11多线程之future和promise
std::future和promise的作用是在不同线程之间传递数据。使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问;而且指针的方式传递的数据是固定的,如果更改数据类型,那么还需要更改有关的接口,比较麻烦;promise支持泛型的操作,更加方便编程处理。
假设线程1需要线程2的数据,那么组合使用方式如下:
线程1初始化一个promise对象和一个future对象,promise传递给线程2,相当于线程2对线程1的一个承诺;future相当于一个接受一个承诺,用来获取未来线程2传递的值
线程2获取到promise后,需要对这个promise传递有关的数据,之后线程1的future就可以获取数据了。
如果线程1想要获取数据,而线程2未给出数据,则线程1阻塞,直到线程2的数据到达。
std::future对象可以和asych,std::packaged_task,std::promise一起使用。这篇文章集中讨论std::future和std::promise。
我们经常会遇到需要得到线程返回结果的情况,现在的问题是我们如何实现。
举个例子:
假设在程序中,我们创建了一个压缩给定文件夹的线程,并且我们希望该线程能够返回新的zip文件的名称和大小。
有两种实现方式:
1、老方法:使用指针在线程间共享数据
传递一个指针到新的线程中,该线程将在其中设置数据。直到主线程继续等待使用条件变量。当新线程设置数据并通知条件变量时,主线程将唤醒并从该指针处获取数据。
为了实现这一简单功能,我们使用了一个条件变量、一个mutex锁和一个指针,来实现捕获返回值。
如果我们想要该线程在不同的时间点返回3个不同的值,问题会变得更加复杂,有没有一种简单的方法来从线程处获取返回值呢?
答案是使用std::future
2、c++11的方法:使用std::future 和 std::promise
std::future是一个类模板(class template),其对象存储未来的值,
到底什么是未来的值呢?
事实上,一个std::future对象在内部存储一个将来会被赋值的值,并提供了一个访问该值的机制,通过get()成员函数实现。但如果有人视图在get()函数可用之前通过它来访问相关的值,那么get()函数将会阻塞,直到该值可用。
std::promise也是一个类模板,其对象有可能在将来对值进行赋值,每个std::promise对象有一个对应的std::future对象,一旦由std::promise对象设置,std::future将会对其赋值。
std::promise对象与其管理的std::future对象共享数据。逐步解析
在线程1中创建一个std::promise对象
std::promise<int> promiseObj;
目前为止,该promise对象没有任何管理的值,但它承诺肯定会有人对其进行赋值,一旦被赋值,就可以通过其管理的std::future对象来获取该值。
但是,假设线程1创建了该promise对象并将其传给线程2,那么线程1怎样知道线程2什么时候会对promise对象进行赋值呢?
答案是使用std::future对象
每个std::promise对象都有个对应的std::future对象,其他人可以通过它来获取promise设置的值。
所以,线程1将会创建std::promise对象,然后在将其传递给线程2之前从它那里获取std::future对象。
std::future<int> futureObj = promiseObj.get_future();
现在,线程1将promiseObj传递给线程2.
那么线程1将会获取到线程2通过std::future的get函数设置在std::promise中的值,
int val = futureObj.get();
但是如果线程2还没有对该值进行设置,那么这个调用将会阻塞,直到线程2在promise对象中对该值进行设置。
promiseObj.set_value(45);
一个简单的说明流程:
简单的代码示例:
#include <iostream>
#include <functional>
#include <future>
#include <thread>
#include <chrono>
#include <cstdlib>void thread_set_promise(std::promise<int>& promiseObj) {std::cout << "In a thread, making data...\n";std::this_thread::sleep_for(std::chrono::milliseconds(1000));promiseObj.set_value(35);std::cout << "Finished\n";
}int main() {std::promise<int> promiseObj;std::future<int> futureObj = promiseObj.get_future();std::thread t(&thread_set_promise, std::ref(promiseObj));std::cout << futureObj.get() << std::endl;t.join();system("pause");return 0;
}
输出结果:
如果std::promise对象在赋值之前被销毁,那么管理的std::future对象上的get()调用将会抛出异常。
除此之外,如果想要线程在不同时间点返回多个值,只需要在线程中传输多个std::promise对象,并从相关的多个std::futur对象中获取多个返回值。
原文链接:
https://blog.csdn.net/lijinqi1987/article/details/78507623
https://blog.csdn.net/qq_35976351/article/details/84186042
C++11多线程之future和promise相关推荐
- C++ 11 多线程之future
什么是std::future? 在C++ 11中std::future是一个绕不开的新特性,因为他的引入极大提高了大家编码的效率.std::future是一个类模板,它将存放着一个未来的变量,而这个变 ...
- Scala教程之:Future和Promise
文章目录 定义返回Future的方法 阻塞方式获取Future的值 非阻塞方式获取Future的值 Future链 flatmap VS map Future.sequence() VS Future ...
- c++11多线程之packaged_task<>介绍与实例
本节讨论c++11中std::packaged_task的特性与使用方法 std::packaged_task<> std::packaged_task<>是一个类模板,代表一 ...
- future java 多线程_Java多线程之Future与FutureTask
一:Future 在使用实现Callable创建线程时,call()方法是有返回值的.那么,我们在编程时用什么来代表这个 线程执行后才能返回的未来结果 呢?那就是 Future类型. 顾名思义,Fut ...
- C++中Future和Promise的一种简单实现
女主宣言 由于工作需求,笔者最近在阅读 Pulsar C++ 客户端的实现,发现该客户端虽然是基于 C++11 编写的,但却自己编写了 Future 和 Promise 类,随着阅读的深入,也体会到了 ...
- 中的listeners_C++中Future和Promise的一种简单实现
女主宣言 由于工作需求,笔者最近在阅读 Pulsar C++ 客户端的实现,发现该客户端虽然是基于 C++11 编写的,但却自己编写了 Future 和 Promise 类,随着阅读的深入,也体会到了 ...
- Java多线程之Callable、Future和FutureTask
Java多线程之Callable接口 自己想总结一下的,看到一篇总结的更好的博客,就转载了,突然感觉真轻松,哈哈哈哈 文章转载于:Matrix海子:Java并发编程:Callable.Future和F ...
- C++11 并发指南四(future 详解一 std::promise 介绍)
前面两讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread 和 std::m ...
- C++11多线程---future和promise
future和promise的作用是在不同线程之间传递数据.使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问:而且指针的方式传递的数据是固定的,如果更改数据类型,那么还需要 ...
最新文章
- HTML5 localStorage本地存储
- 如何在linux上安装sqlite数据库
- 信息学奥赛一本通 1134:合法C标识符 | OpenJudge NOI 1.7 06
- easyUI combobox启用禁用功能写法
- java线程本地存储_[并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)-win32和pthread比较]...
- Stm32:半主机模式
- 定时锁定计算机怎么设置方法,电脑定时锁屏怎么设置
- 【转】斐讯K2刷华硕固件教程
- 启用计算机的快捷键,电脑启动热键对照表
- OpenMP: sections分段并行
- Ubuntu 20.04系统中Sage(sagemath)安装及使用详细过程
- 云洲智能,能否成为科创板无人船艇第一股?
- 2020最新整理JAVA面试题附答案
- FFplay序列号分析
- oracle增加列 reorg,Reorg rebuild 重建表和表上的索引
- 拯救BUG 10五笔输入法Shift键切换中英文问题
- Windows10关闭指定端口号命令
- 计算机的新兴技术在测绘工程领域的应用,GPS测绘技术在测绘工程中的具体应用...
- .NET获取快递100提供的查询快递信息的方法
- 【模型库】KR 10 R900 sixx CR小型机器人
热门文章
- java 静态方法_新手学Java,哪些知识点可以优先掌握?
- qtdesigner设计表格_实例9 利用Qt Designer设计一个对话框
- PHP婚庆网站论文,jsp婚庆网站
- java ftp限速_为什么Java FTP客户端的传输速率存在很大差异
- css3 下边框缓缓划过_一篇文章带你了解CSS3按钮知识
- linux prc 时区,授时时区问题解决
- 计算机还是数学竞赛内容吗,除了AMC,数学牛娃还能参加什么高含金量的数学竞赛...
- vue 声明周期函数_Vue_生命周期函数
- mac 10.10 apache php,在Mac上10分钟搞定Apache服务器配置
- Shell运算符及条件判断