C++ 11 多线程之future
什么是std::future?
在C++ 11中std::future是一个绕不开的新特性,因为他的引入极大提高了大家编码的效率。std::future是一个类模板,它将存放着一个未来的变量,而这个变量可以通过std::future提供的成员函数std::future::get()来得到。
std::future从何而来?
std::future通常可以通过调用函数(provider)来构造对象,provider一般指std::async、std::promise、std::packaged_task
- std::async 函数
- std::promise::get_future:get_future 为 promise 类的成员函数
- std::packaged_task::get_future: get_future为 packaged_task 的成员函数
如果std::future这个变量尚未被赋值之前,就有其他线程试图通过std::future::get()获取这个变量,那么这个调用std::future::get()线程将会被阻塞到这个变量可以获取为止,才会继续执行。
std::future的构成
基础函数(构造、析构、赋值):
std::future 的拷贝构造函数是被禁用的,只提供了默认的构造函数和移动构造函数。另外,std::future的赋值构造函数禁用,只提供了 move 赋值操作share函数:获取共享的future,返回一个std::shared_future对象,该对象获取future对象的共享状态。future对象将不再有效。
valid函数:检查共享状态的有效性,返回当前的future对象是否与共享状态关联。一旦调用了std::future::get()函数,再调用此函数将返回false。
wait函数:等待共享状态就绪,如果共享状态尚未就绪(即提供者尚未设置其值或异常),则该函数将阻塞调用者的线程直至共享状态就绪后,该函数将取消阻塞并void返回。
wait_for函数:等待共享状态在指定的时间内(时间片)准备就绪,如果同样尚未就绪,则该函数将阻塞调用者的线程直到就绪或已达到设置超时的时间。
此函数的返回值类型为枚举类future_status。- ready:共享状态已就绪或者异常;
- timeout:在规定的时间内未就绪;
- deferred:异步函数操作还没开始;
wait_until函数:等待共享状态在指定的时间点(时间点)准备就绪,如果同样尚未就绪,则该函数将阻塞调用者的线程直到就绪或已达到设置超时的时间。
此函数的返回值类型为枚举类future_status,具体释义同上
代码释义
#include <future>
#include <iostream>
#include <chrono>
using namespace std;
namespace {int TestFunc(int x){cout << "thread id=" << std::this_thread::get_id() << endl;int result = 0;for (int i = 0; i < x; i++) {result += 3;std::this_thread::sleep_for(std::chrono::milliseconds(100));}return result;}
} // namespace
void Test_share()
{std::future<int> ret_data = std::async([] { return 50; });std::shared_future<int> shared_ret_data = ret_data.share();try {// share()后,ret_data对象将变得无效,调用空指针std::cout << "ret_data valid: " << ret_data.valid() << endl;std::cout << "ret_data get: " << ret_data.get() << endl;} catch (const std::future_error& e) {// exception: std::future_errorstd::cout << "future_error : " << e.what() << std::endl;}//std::shared_future对象,get函数可以被多次访问std::cout << "value: " << shared_ret_data.get() << endl;std::cout << "its double: " << shared_ret_data.get() * 2 << endl;
}
void Test_valid_get()
{std::future<int> ret_data = std::async([] { return 50; });cout << ret_data.valid() << endl;//获取有效性cout << ret_data.get() << endl; //first getcout << ret_data.valid() << endl;//获取有效性try {std::cout << "ret_data get: " << ret_data.get() << endl; // second get} catch (const std::future_error& e) {// exception: std::future_errorstd::cout << "future_error : " << e.what() << std::endl;}
}
void Test_wait()
{cout << "thread id=" << std::this_thread::get_id() << " " << __FUNCTION__ << endl;std::future<int> ret_data = std::async(TestFunc, 5);std::cout << "wait..." << endl;ret_data.wait();std::cout << "ready..." << endl;std::cout << "ret_data get: " << ret_data.get() << endl; // second get
}
void Test_wait_()
{ /*enum class future_status { // names for timed wait function returnsready,timeout,deferred};*/int call_sum = 0;while (cin >> call_sum) {cout << "thread id=" << std::this_thread::get_id() << " " << __FUNCTION__ << endl;std::future<int> ret_data = std::async(TestFunc, call_sum);std::cout << "wait start" << endl;std::chrono::milliseconds span(200);std::future_status ret_state = ret_data.wait_for(span);//获取状态//std::future_status ret_state =// ret_data.wait_until(std::chrono::system_clock::now() + std::chrono::milliseconds(200)); //获取状态,200ms后std::cout << "wait end state=" << static_cast<int>(ret_state) << endl;try {std::cout << "ret_data get: " << ret_data.get() << endl; // second get} catch (const std::future_error& e) {// exception: std::future_errorstd::cout << "future_error : " << e.what() << std::endl;}}
}
int main()
{Test_share();cout << "======================================================" << endl;Test_valid_get();cout << "======================================================" << endl;Test_wait();cout << "======================================================" << endl;Test_wait_();cout << "======================================================" << endl;
}
结果
引申std::shared_future
std::shared_future 与std::future接口基本一致。
与std::shared_future关系
- std::shared_future对象可以通过std::future对象进行隐式转换,也可以通过显示调用std::future::share显示转换,在这两种情况下,原来的std::future对象都会无效。
- 当你需要具有std::future的多个有效拷贝时会用到std::shared_future;或者多个使用者使用std::future时也会用到std::shared_future
主要在用法上有区别
- 支持copy(拷贝构造函数,拷贝赋值操作);
- get()是一个const成员函数,返回一个const reference指向“存储于shared state”的值,通过shared_future::get检索的值不会释放共享对象的所有权
- 共享状态(shared state)的生存期至少要持续到与之关联的最后一个对象被销毁为止。
参考连接:future实现
C++ 11 多线程之future相关推荐
- C++11多线程之future和promise
std::future和promise的作用是在不同线程之间传递数据.使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问:而且指针的方式传递的数据是固定的,如果更改数据类型, ...
- 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 ...
- Java多线程之Callable、Future和FutureTask
Java多线程之Callable接口 自己想总结一下的,看到一篇总结的更好的博客,就转载了,突然感觉真轻松,哈哈哈哈 文章转载于:Matrix海子:Java并发编程:Callable.Future和F ...
- 多线程之CompletableFuture和ParallelStream应该使用哪个?
多线程之CompletableFuture和ParallelStream应该使用哪个 简介 实例场景 测试代码 开始测试 总结 备注 简介 随着用户对性能和体验的要求越来越高,异步在项目中用的也就越来 ...
- JAVA多线程之wait/notify
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...
- 多线程之CompletableFuture全方面解析
多线程之CompletableFuture全方面解析 目录: 前言: 在我们写的一个底层Api中,由于上亿级数据量情况下,查询效率较慢,本篇文档记录一下优化过程所用技术栈CompletableFu ...
- 异步多线程之ThreadPool详解
上一篇:异步多线程之Thread 下一篇:异步多线程之入Task 介绍 ThreadPool 是 .net 2.0 时代的产物,有了 Thread 为什么还会有 ThreadPool 呢?Thread ...
- Android多线程之ArrayBlockingQueue源码解析
阻塞队列系列 Android多线程之LinkedBlockingQueue源码解析 Android多线程之SynchronousQueue源码解析 Andorid多线程之DelayQueue源码分析 ...
最新文章
- mysql数据库名虚拟机_linux虚拟机上装mysql数据库
- HTML基础-第二讲
- Andorid之为何要用到NDK?
- 从DataTable导出Excel,并下载,删除Excel进程。
- 快速排序 - python版超详细讲解
- python中的多线程的优点_Python中多线程编程的优点是什么?
- large margin-人脸识别
- cxf超时设置不起效_晚上不限时,白天1小时!上海限时长停车场来了
- bzoj 2151 种树 —— 思路+链表
- python编写代码自动运行程序_利用Python编写自动打开指定软件的程序
- 电子阅读器行业市场研究分析及未来趋势预测分析
- Abaqus有限元分析软件介绍
- 步进电机应用c语言程序设计实例,步进电机C语言程序.doc
- 推理的2种方式:演绎和归纳
- VMWare IOS MAC分区教程
- 汉语中的 熟语中的成语900个
- mysql count的用法_155、MySQL入门(五):SUM and COUNT用法
- C++课程设计报告——简易五子棋游戏
- 外贸电商数据平台(一) shopee
- java实现qlearning,DQN(Deep Q-learning)入门教程(一)之强化学习介绍
热门文章
- java jdk12_JDK 12:Java 12中的新功能
- 二维码解码器Zbar+VS2010开发环境配置(使用opencv库)
- 【小王的安卓之路】Android原生网络请求
- Storm专题一、Storm DRPC 分布式计算
- 码云 gitee 下载压缩包 未知文件格式 解压错误?像极了 Github
- 传奇列表上传登录器公告小窗口怎么修改
- ROS2机器人操作系统简介2021英文字幕版本
- 解决Antimalware Service Executable(windows defender)占用过高CPU和内存的方法
- 中国矿业大学算法概论作业一A、锯木棒
- axios与拦截器的简单结合