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相关推荐

  1. C++ 11 多线程之future

    什么是std::future? 在C++ 11中std::future是一个绕不开的新特性,因为他的引入极大提高了大家编码的效率.std::future是一个类模板,它将存放着一个未来的变量,而这个变 ...

  2. Scala教程之:Future和Promise

    文章目录 定义返回Future的方法 阻塞方式获取Future的值 非阻塞方式获取Future的值 Future链 flatmap VS map Future.sequence() VS Future ...

  3. c++11多线程之packaged_task<>介绍与实例

    本节讨论c++11中std::packaged_task的特性与使用方法 std::packaged_task<> std::packaged_task<>是一个类模板,代表一 ...

  4. future java 多线程_Java多线程之Future与FutureTask

    一:Future 在使用实现Callable创建线程时,call()方法是有返回值的.那么,我们在编程时用什么来代表这个 线程执行后才能返回的未来结果 呢?那就是 Future类型. 顾名思义,Fut ...

  5. C++中Future和Promise的一种简单实现

    女主宣言 由于工作需求,笔者最近在阅读 Pulsar C++ 客户端的实现,发现该客户端虽然是基于 C++11 编写的,但却自己编写了 Future 和 Promise 类,随着阅读的深入,也体会到了 ...

  6. 中的listeners_C++中Future和Promise的一种简单实现

    女主宣言 由于工作需求,笔者最近在阅读 Pulsar C++ 客户端的实现,发现该客户端虽然是基于 C++11 编写的,但却自己编写了 Future 和 Promise 类,随着阅读的深入,也体会到了 ...

  7. Java多线程之Callable、Future和FutureTask

    Java多线程之Callable接口 自己想总结一下的,看到一篇总结的更好的博客,就转载了,突然感觉真轻松,哈哈哈哈 文章转载于:Matrix海子:Java并发编程:Callable.Future和F ...

  8. C++11 并发指南四(future 详解一 std::promise 介绍)

    前面两讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread 和 std::m ...

  9. C++11多线程---future和promise

    future和promise的作用是在不同线程之间传递数据.使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问:而且指针的方式传递的数据是固定的,如果更改数据类型,那么还需要 ...

最新文章

  1. HTML5 localStorage本地存储
  2. 如何在linux上安装sqlite数据库
  3. 信息学奥赛一本通 1134:合法C标识符 | OpenJudge NOI 1.7 06
  4. easyUI combobox启用禁用功能写法
  5. java线程本地存储_[并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)-win32和pthread比较]...
  6. Stm32:半主机模式
  7. 定时锁定计算机怎么设置方法,电脑定时锁屏怎么设置
  8. 【转】斐讯K2刷华硕固件教程
  9. 启用计算机的快捷键,电脑启动热键对照表
  10. OpenMP: sections分段并行
  11. Ubuntu 20.04系统中Sage(sagemath)安装及使用详细过程
  12. 云洲智能,能否成为科创板无人船艇第一股?
  13. 2020最新整理JAVA面试题附答案
  14. FFplay序列号分析
  15. oracle增加列 reorg,Reorg rebuild 重建表和表上的索引
  16. 拯救BUG 10五笔输入法Shift键切换中英文问题
  17. Windows10关闭指定端口号命令
  18. 计算机的新兴技术在测绘工程领域的应用,GPS测绘技术在测绘工程中的具体应用...
  19. .NET获取快递100提供的查询快递信息的方法
  20. 【模型库】KR 10 R900 sixx CR小型机器人

热门文章

  1. java 静态方法_新手学Java,哪些知识点可以优先掌握?
  2. qtdesigner设计表格_实例9 利用Qt Designer设计一个对话框
  3. PHP婚庆网站论文,jsp婚庆网站
  4. java ftp限速_为什么Java FTP客户端的传输速率存在很大差异
  5. css3 下边框缓缓划过_一篇文章带你了解CSS3按钮知识
  6. linux prc 时区,授时时区问题解决
  7. 计算机还是数学竞赛内容吗,除了AMC,数学牛娃还能参加什么高含金量的数学竞赛...
  8. vue 声明周期函数_Vue_生命周期函数
  9. mac 10.10 apache php,在Mac上10分钟搞定Apache服务器配置
  10. Shell运算符及条件判断