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

  1. C++11多线程之future和promise

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

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

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

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

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

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

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

  5. 多线程之CompletableFuture和ParallelStream应该使用哪个?

    多线程之CompletableFuture和ParallelStream应该使用哪个 简介 实例场景 测试代码 开始测试 总结 备注 简介 随着用户对性能和体验的要求越来越高,异步在项目中用的也就越来 ...

  6. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  7. 多线程之CompletableFuture全方面解析

    多线程之CompletableFuture全方面解析 目录: 前言: ​ 在我们写的一个底层Api中,由于上亿级数据量情况下,查询效率较慢,本篇文档记录一下优化过程所用技术栈CompletableFu ...

  8. 异步多线程之ThreadPool详解

    上一篇:异步多线程之Thread 下一篇:异步多线程之入Task 介绍 ThreadPool 是 .net 2.0 时代的产物,有了 Thread 为什么还会有 ThreadPool 呢?Thread ...

  9. Android多线程之ArrayBlockingQueue源码解析

    阻塞队列系列 Android多线程之LinkedBlockingQueue源码解析 Android多线程之SynchronousQueue源码解析 Andorid多线程之DelayQueue源码分析 ...

最新文章

  1. mysql数据库名虚拟机_linux虚拟机上装mysql数据库
  2. HTML基础-第二讲
  3. Andorid之为何要用到NDK?
  4. 从DataTable导出Excel,并下载,删除Excel进程。
  5. 快速排序 - python版超详细讲解
  6. python中的多线程的优点_Python中多线程编程的优点是什么?
  7. large margin-人脸识别
  8. cxf超时设置不起效_晚上不限时,白天1小时!上海限时长停车场来了
  9. bzoj 2151 种树 —— 思路+链表
  10. python编写代码自动运行程序_利用Python编写自动打开指定软件的程序
  11. 电子阅读器行业市场研究分析及未来趋势预测分析
  12. Abaqus有限元分析软件介绍
  13. 步进电机应用c语言程序设计实例,步进电机C语言程序.doc
  14. 推理的2种方式:演绎和归纳
  15. VMWare IOS MAC分区教程
  16. 汉语中的 熟语中的成语900个
  17. mysql count的用法_155、MySQL入门(五):SUM and COUNT用法
  18. C++课程设计报告——简易五子棋游戏
  19. 外贸电商数据平台(一) shopee
  20. java实现qlearning,DQN(Deep Q-learning)入门教程(一)之强化学习介绍

热门文章

  1. java jdk12_JDK 12:Java 12中的新功能
  2. 二维码解码器Zbar+VS2010开发环境配置(使用opencv库)
  3. 【小王的安卓之路】Android原生网络请求
  4. Storm专题一、Storm DRPC 分布式计算
  5. 码云 gitee 下载压缩包 未知文件格式 解压错误?像极了 Github
  6. 传奇列表上传登录器公告小窗口怎么修改
  7. ROS2机器人操作系统简介2021英文字幕版本
  8. 解决Antimalware Service Executable(windows defender)占用过高CPU和内存的方法
  9. 中国矿业大学算法概论作业一A、锯木棒
  10. axios与拦截器的简单结合