std::shared_future

在之前笔记C++11笔记-多线程-细说Future中,std::future提供了“处理并发运算之未来结果”的能力,但是只能处理一次结果,第二次调用get()会导致不可以预期的行为;因为调用get()后会将future的state状态置为无效状态;
在项目的不同场景中,也会有多次处理“并发运算之未来结果”的情况,特别是当多个其他线程都想处理这份结果时。所有C++标准库提供了std::shared_future,可以多次调用get(),产生相同结果或获得任务抛出的异常;

与future不同之处

shared_future提供的语义和接口与future相同,但有以下差异:
1.允许多次调用get()。因此get()必不令其状态失效;
2.支持copy(拷贝构造函数,拷贝赋值操作);
3.get()是一个const成员函数,返回一个const reference指向“存储于shared state”的值(意味着你必须确定“被返回的reference”的寿命短于state);std::future的get()是个non-const成员函数,返回一个move-assigned拷贝,除非这个class“被一个reference类型实现特化”;
4.不提供share();
注意:程序员在不同的线程内处理non-const reference时,一定要清楚他们在做些什么

示例代码

#include <future>
#include <thread>
#include <exception>
#include <stdexcept>
#include <iostream>
using namespace std;int queryNumber()
{cout << "read nuber: ";int num = 0;cin >> num;if (!cin){throw runtime_error("no number read");}return num;
}void doSomthing(char c,shared_future<int> f)
{try{int num = f.get();for (size_t i = 0; i < num; i++){this_thread::sleep_for(chrono::milliseconds(100));cout.put(c).flush();}}catch (const std::exception& e){cerr << "EXCEPTION in thread " << this_thread::get_id() << ": " << e.what() << endl;}}int main()
{try{shared_future<int> f = async(queryNumber);auto f1 = async(launch::async, doSomthing, '.', f);auto f2 = async(launch::async, doSomthing, '+', f);auto f3 = async(launch::async, doSomthing, '*', f);f1.get();f2.get();f3.get();}catch (const std::exception& e){cout << "\nException:" << e.what() << endl;}cout << "\ndone" << endl;system("pause");
}

运行结果如下:
输入12后的结果;

所有shared future object共享所谓shared state,后者由async()建立,用来存放目标函数的运行结果(也存放函数本身——如果它被推迟执行的话);
输入x后的结果:

如果queryNumber()抛出异常(当程序未能读到整数时),那么对doSomething()的每一次调用都会获得因f.get()而来的异常,于是对应的异常处理便会发生;

注意:使用shared_future可能会造成数据竞争的出现;需要小心使用;
Lawrence Crowl ——“如果代码紧紧保持着高度协调,以by reference方式传递是好的。但如果代码进入一个对于目标和限制都不甚了解的地带,那么还是以by value方式传递较佳。复制shared future虽然带来了高昂的成本,毕竟比不上在一个大系统中跳出一个潜伏bug来的昂贵”;

文献

1.《C++标准库》第二版;

C++标准库笔记-多线程-shared_future-future的补充扩展相关推荐

  1. Python标准库笔记(9) — functools模块

    functools 作用于函数的函数 functools 模块提供用于调整或扩展函数和其他可调用对象的工具,而无需完全重写它们. 装饰器 partial 类是 functools 模块提供的主要工具, ...

  2. 不属于python标准库的是_Python标准库笔记(11) — Op

    Operator--标准功能性操作符接口. 代码中使用迭代器时,有时必须要为一个简单表达式创建函数.有些情况这些函数可以用一个lambda函数实现,但是对于某些操作,根本没必要去写一个新的函数.因此o ...

  3. python string模块template_Python标准库笔记(1) — string模块

    String模块包含大量实用常量和类,以及一些过时的遗留功能,并还可用作字符串操作. 1. 常用方法 常用方法描述str.capitalize()把字符串的首字母大写str.center(width) ...

  4. python import re_Python标准库笔记(2) — re模块

    re模块提供了一系列功能强大的正则表达式(regular expression)工具,它们允许你快速检查给定字符串是否与给定的模式匹配(match函数), 或者包含这个模式(search函数).正则表 ...

  5. python pprint_Python标准库笔记(8) — pprint模块

    目录[-] pprint -- 更美观的打印数据结构 pprint 模块包含一个"美观打印器(PrettyPrinter)",用于产生美观的数据结构视图.格式化程序生成可以由解释器 ...

  6. C++标准库笔记:13.5 标准I/O函数

    前言 同读写格式化数据的>>,<<操作符不同, 使用Stream成员函数读取数据时,不跳过起始空格. 处理异常不同:使用成员函数,如果在读取期间,发生异常,不论源自某个被调用函 ...

  7. c运行库、c标准库、windows API的区别和联系

    c运行库.c标准库.windows API的区别和联系 C运行时库函数 C运行时库函数是指C语言本身支持的一些基本函数,通常是汇编直接实现的.    API函数 API函数是操作系统为方便用户设计应用 ...

  8. C++著名类库和C++标准库介绍

    C++著名类库 1.C++各大有名库的介绍--C++标准库  2.C++各大有名库的介绍--准标准库Boost  3.C++各大有名库的介绍--GUI  4.C++各大有名库的介绍--网络通信  5. ...

  9. java stl stack_C++标准库之stack

    C++库以提供"模板"为主.所谓模板,是指不必预先制定类型的函数或类.我们可以借助STL(标准模板库 Standard Template Library, STL)提供的高效算法来 ...

最新文章

  1. Silverlight如何与JS相互调用
  2. 二进制包安装MySQL数据库
  3. IDEA如何生成get和set方法
  4. [转]Winform不规则窗体的实现心得
  5. 通知NSNotificationCenter
  6. java多线程生产消费者_java多线程 生产消费者模型
  7. [BJOI2017]开车
  8. SELECT 基本语法结构
  9. java数组的定义(菜鸟教程)
  10. Print2Flash 3汉化破解版下载
  11. 利用echarts做堆积折线图
  12. ASP.NET Core 在 IIS 上的进程内 (InProcess) 托管
  13. 【读心术】之微表情——《Lie to me 》摘自百度百科
  14. SAN计算机,什么是SAN网络存储
  15. CSS中常用的几种选择器是哪几种呢?
  16. Puppeteer之Pyppeteer——浏览某短视频,获取点赞和评论,收藏,转发数(5)
  17. 如何平衡新老策略的好与坏,一道常见风控送命题解答
  18. Linux驱动01 - Timer
  19. Factory Track 7 链接 Infor CloudSuite Industrial 10 操作设置
  20. SiTime硅晶振和石英晶振的冲击和振动性能比较

热门文章

  1. 百度IFE2018任务--20-21天
  2. 整理任正非思想:胜利祝酒辞-1994
  3. python怎么创建文件夹视频_怎么用python创建文件夹
  4. 初玩scrapy:爬取淘票票(1)
  5. 影像组学:医学影像学与个性化精准医疗的桥梁
  6. 【笔记本保养】老机器的保养注意事项
  7. 动态Probit模型及Stata实现
  8. 亚马逊AWS云架构支柱与数字化转型
  9. 无监督 自监督---综述
  10. String index out of range: -824264796 不明的原因导致驱动程序造成失败,请回报这个例外。