C++11 并发指南四(future 详解一 std::promise 介绍)
前面两讲《C++11 并发指南二(std::thread 详解)》,《C++11 并发指南三(std::mutex 详解)》分别介绍了 std::thread 和 std::mutex,相信读者对 C++11 中的多线程编程有了一个最基本的认识,本文将介绍 C++11 标准中 <future> 头文件里面的类和相关函数。
<future> 头文件中包含了以下几个类和函数:
- Providers 类:std::promise, std::package_task
- Futures 类:std::future, shared_future.
- Providers 函数:std::async()
- 其他类型:std::future_error, std::future_errc, std::future_status, std::launch.
std::promise 类介绍
promise 对象可以保存某一类型 T 的值,该值可被 future 对象读取(可能在另外一个线程中),因此 promise 也提供了一种线程同步的手段。在 promise 对象构造时可以和一个共享状态(通常是std::future)相关联,并可以在相关联的共享状态(std::future)上保存一个类型为 T 的值。
可以通过 get_future 来获取与该 promise 对象相关联的 future 对象,调用该函数之后,两个对象共享相同的共享状态(shared state)
- promise 对象是异步 Provider,它可以在某一时刻设置共享状态的值。
- future 对象可以异步返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标志变为 ready,然后才能获取共享状态的值。
下面以一个简单的例子来说明上述关系
#include <iostream> // std::cout #include <functional> // std::ref #include <thread> // std::thread #include <future> // std::promise, std::futurevoid print_int(std::future<int>& fut) {int x = fut.get(); // 获取共享状态的值.std::cout << "value: " << x << '\n'; // 打印 value: 10. }int main () {std::promise<int> prom; // 生成一个 std::promise<int> 对象.std::future<int> fut = prom.get_future(); // 和 future 关联.std::thread t(print_int, std::ref(fut)); // 将 future 交给另外一个线程t.prom.set_value(10); // 设置共享状态的值, 此处和线程t保持同步. t.join();return 0; }
std::promise 构造函数
default (1) |
promise(); |
---|---|
with allocator (2) |
template <class Alloc> promise (allocator_arg_t aa, const Alloc& alloc); |
copy [deleted] (3) |
promise (const promise&) = delete; |
move (4) |
promise (promise&& x) noexcept; |
- 默认构造函数,初始化一个空的共享状态。
- 带自定义内存分配器的构造函数,与默认构造函数类似,但是使用自定义分配器来分配共享状态。
- 拷贝构造函数,被禁用。
- 移动构造函数。
另外,std::promise 的 operator= 没有拷贝语义,即 std::promise 普通的赋值操作被禁用,operator= 只有 move 语义,所以 std::promise 对象是禁止拷贝的。
例子:
#include <iostream> // std::cout #include <thread> // std::thread #include <future> // std::promise, std::future std::promise<int> prom;void print_global_promise () {std::future<int> fut = prom.get_future();int x = fut.get();std::cout << "value: " << x << '\n'; }int main () {std::thread th1(print_global_promise);prom.set_value(10);th1.join();prom = std::promise<int>(); // prom 被move赋值为一个新的 promise 对象. std::thread th2 (print_global_promise);prom.set_value (20);th2.join();return 0; }
std::promise::get_future 介绍
该函数返回一个与 promise 共享状态相关联的 future 。返回的 future 对象可以访问由 promise 对象设置在共享状态上的值或者某个异常对象。只能从 promise 共享状态获取一个 future 对象。在调用该函数之后,promise 对象通常会在某个时间点准备好(设置一个值或者一个异常对象),如果不设置值或者异常,promise 对象在析构时会自动地设置一个 future_error 异常(broken_promise)来设置其自身的准备状态。上面的例子中已经提到了 get_future,此处不再重复。
std::promise::set_value 介绍
generic template (1) |
void set_value (const T& val); void set_value (T&& val); |
---|---|
specializations (2) |
void promise<R&>::set_value (R& val); // when T is a reference type (R&) void promise<void>::set_value (void); // when T is void |
设置共享状态的值,此后 promise 的共享状态标志变为 ready.
std::promise::set_exception 介绍
为 promise 设置异常,此后 promise 的共享状态变标志变为 ready,例子如下,线程1从终端接收一个整数,线程2将该整数打印出来,如果线程1接收一个非整数,则为 promise 设置一个异常(failbit) ,线程2 在std::future::get 是抛出该异常。
#include <iostream> // std::cin, std::cout, std::ios #include <functional> // std::ref #include <thread> // std::thread #include <future> // std::promise, std::future #include <exception> // std::exception, std::current_exceptionvoid get_int(std::promise<int>& prom) {int x;std::cout << "Please, enter an integer value: ";std::cin.exceptions (std::ios::failbit); // throw on failbittry {std::cin >> x; // sets failbit if input is not int prom.set_value(x);} catch (std::exception&) {prom.set_exception(std::current_exception());} }void print_int(std::future<int>& fut) {try {int x = fut.get();std::cout << "value: " << x << '\n';} catch (std::exception& e) {std::cout << "[exception caught: " << e.what() << "]\n";} }int main () {std::promise<int> prom;std::future<int> fut = prom.get_future();std::thread th1(get_int, std::ref(prom));std::thread th2(print_int, std::ref(fut));th1.join();th2.join();return 0; }
std::promise::set_value_at_thread_exit 介绍
设置共享状态的值,但是不将共享状态的标志设置为 ready,当线程退出时该 promise 对象会自动设置为 ready。如果某个 std::future 对象与该 promise 对象的共享状态相关联,并且该 future 正在调用 get,则调用 get 的线程会被阻塞,当线程退出时,调用 future::get 的线程解除阻塞,同时 get 返回 set_value_at_thread_exit 所设置的值。注意,该函数已经设置了 promise 共享状态的值,如果在线程结束之前有其他设置或者修改共享状态的值的操作,则会抛出 future_error( promise_already_satisfied )。
std::promise::swap 介绍
交换 promise 的共享状态。
C++11 并发指南四(future 详解一 std::promise 介绍)相关推荐
- C++11 并发指南四(future 详解二 std::packaged_task 介绍)
上一讲<C++11 并发指南四(<future> 详解一 std::promise 介绍)>主要介绍了 <future> 头文件中的 std::promise 类, ...
- C++11 并发指南四(future 详解三 std::future std::shared_future)
上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...
- C++11 并发指南三(Lock 详解)(转载)
multithreading 多线程 C++11 C++11多线程基本使用 C++11 并发指南三(Lock 详解) 在 <C++11 并发指南三(std::mutex 详解)>一文中我们 ...
- C++11 并发指南三(Lock 详解)
在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...
- 并发编程四 synchronized详解
一 设计同步器的意义 多线程编程中,有可能会出现多个线程同时访问同一个共享.可变资源的情况,这个资源我们称之其为临界资源:这种资源可能是:对象.变量.文件等. 共享:资源可以由多个线程同时访问 可变: ...
- C++11 并发指南六(atomic 类型详解三 std::atomic (续))
C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...
- C++11 并发指南六(atomic 类型详解四 C 风格原子操作介绍)
前面三篇文章<C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)>.<C++11 并发指南六( <atomic> 类型详解二 std::at ...
- C++11 并发指南三(std::mutex 详解)
上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法. Mutex ...
- 【转】C++11 并发指南五(std::condition_variable 详解)
http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三 ...
最新文章
- 推荐一个 Java 接口快速开发框架
- Linux动态频率调节系统CPUFreq之一:概述【转】-- 非常好的博客
- 第14条:理解“类对象”的用意
- NeuCF源码中用到的模块(函数)
- 十万服务器秒级管控 腾讯云如何将AIOps用于日常管理?
- mysql永远不用utf8_永远不要在 MySQL 中使用「utf8」
- 解决172.17 或者172.18 机房环境下harbor服务器不通的问题
- 代码优化能减少多少运行速度_35 个小细节,提升 Java 代码的运行效率!你知道几个?...
- 达人管理系统(CRM)原型图
- ArrayList错误:java.util.ConcurrentModificationException:null
- 矩阵的广义逆——减号、加号广义逆的求法
- 读周志华《机器学习》第一章有感(白话总结)
- 电脑桌面打开计算机窗口,电脑怎么打开运行窗口
- 北京区块链技术应用协会第一届第四次会员大会顺利召开
- word的链接到前一节消失
- 关于测试架构师的解读
- 正确使用GCC inline assemble 中的 clobber
- Android Studio2.0 教程从入门到精通MAC版 - 安装篇
- python 通达信板块_通达信如何自定义选股,使用python在通达信里面选股
- Excel快速入门01
热门文章
- win7屏保时间设置_论如何优雅的设置手机和电脑时间屏保!
- c语言数组如何把一串数字存入数组_C语言经典编程题(下)
- 最后一周|高级转录组分析和R语言数据可视化第十二期 (线上线下同时开课)...
- linux启动脚本添加命令,Linux添加shell(.sh)脚本并添加定时任务
- P1423 小玉在游泳(python3实现)
- python中sort和sorted区别_Python中的 sort 和 sorted的用法与区别
- python实训报告50000_Python程序设计 实验报告五
- ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面API错误)
- oracle orapath,SQLNET.ORA中的NAMES.DIRECTORY_PATH设置
- Nacos笔记-对Nacos初步认识