C++标准库笔记-多线程-shared_future-future的补充扩展
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的补充扩展相关推荐
- Python标准库笔记(9) — functools模块
functools 作用于函数的函数 functools 模块提供用于调整或扩展函数和其他可调用对象的工具,而无需完全重写它们. 装饰器 partial 类是 functools 模块提供的主要工具, ...
- 不属于python标准库的是_Python标准库笔记(11) — Op
Operator--标准功能性操作符接口. 代码中使用迭代器时,有时必须要为一个简单表达式创建函数.有些情况这些函数可以用一个lambda函数实现,但是对于某些操作,根本没必要去写一个新的函数.因此o ...
- python string模块template_Python标准库笔记(1) — string模块
String模块包含大量实用常量和类,以及一些过时的遗留功能,并还可用作字符串操作. 1. 常用方法 常用方法描述str.capitalize()把字符串的首字母大写str.center(width) ...
- python import re_Python标准库笔记(2) — re模块
re模块提供了一系列功能强大的正则表达式(regular expression)工具,它们允许你快速检查给定字符串是否与给定的模式匹配(match函数), 或者包含这个模式(search函数).正则表 ...
- python pprint_Python标准库笔记(8) — pprint模块
目录[-] pprint -- 更美观的打印数据结构 pprint 模块包含一个"美观打印器(PrettyPrinter)",用于产生美观的数据结构视图.格式化程序生成可以由解释器 ...
- C++标准库笔记:13.5 标准I/O函数
前言 同读写格式化数据的>>,<<操作符不同, 使用Stream成员函数读取数据时,不跳过起始空格. 处理异常不同:使用成员函数,如果在读取期间,发生异常,不论源自某个被调用函 ...
- c运行库、c标准库、windows API的区别和联系
c运行库.c标准库.windows API的区别和联系 C运行时库函数 C运行时库函数是指C语言本身支持的一些基本函数,通常是汇编直接实现的. API函数 API函数是操作系统为方便用户设计应用 ...
- C++著名类库和C++标准库介绍
C++著名类库 1.C++各大有名库的介绍--C++标准库 2.C++各大有名库的介绍--准标准库Boost 3.C++各大有名库的介绍--GUI 4.C++各大有名库的介绍--网络通信 5. ...
- java stl stack_C++标准库之stack
C++库以提供"模板"为主.所谓模板,是指不必预先制定类型的函数或类.我们可以借助STL(标准模板库 Standard Template Library, STL)提供的高效算法来 ...
最新文章
- Silverlight如何与JS相互调用
- 二进制包安装MySQL数据库
- IDEA如何生成get和set方法
- [转]Winform不规则窗体的实现心得
- 通知NSNotificationCenter
- java多线程生产消费者_java多线程 生产消费者模型
- [BJOI2017]开车
- SELECT 基本语法结构
- java数组的定义(菜鸟教程)
- Print2Flash 3汉化破解版下载
- 利用echarts做堆积折线图
- ASP.NET Core 在 IIS 上的进程内 (InProcess) 托管
- 【读心术】之微表情——《Lie to me 》摘自百度百科
- SAN计算机,什么是SAN网络存储
- CSS中常用的几种选择器是哪几种呢?
- Puppeteer之Pyppeteer——浏览某短视频,获取点赞和评论,收藏,转发数(5)
- 如何平衡新老策略的好与坏,一道常见风控送命题解答
- Linux驱动01 - Timer
- Factory Track 7 链接 Infor CloudSuite Industrial 10 操作设置
- SiTime硅晶振和石英晶振的冲击和振动性能比较