std::future —C++17 多线程

std::future

C++标准程序库使用future来模拟这类一次性事件:若线程需等待某个特定的一次性事件发生,则会以恰当的方式取得一个future,它代表目标事件;接着,该线程就能一边执行其他任务(光顾机场茶座),一边在future上等待;同时,它以短暂的间隔反复查验目标事件是否已经发生(查看出发时刻表)。这个线程也可以转换运行模式,先不等目标事件发生,直接暂缓当前任务,而切换到别的任务,及至必要时,才回头等待future准备就绪。future可能与数据关联(如航班的登机口),也可能未关联。一旦目标事件发生,其future即进入就绪状态,无法重置。

总之,先保存一个事件(创建future对象),在未来获取事件的结果(get)

#pragma once
#include <future>
#include <iostream>
#include <format>
using namespace std;std::string get_answer_from_hard_question()
{std::this_thread::sleep_for(2s);cout << "id: " << std::this_thread::get_id << endl;return string("答案在这\n");
}
void do_something()
{std::this_thread::sleep_for(5s);cout << "id: " << std::this_thread::get_id << endl;cout << "结束任务\n";
}void start()
{std::future<std::string> the_ans = std::async(std::launch::async,get_answer_from_hard_question);do_something();std::cout << std::format("答案是:{}", the_ans.get());
}

创建future对象的方法

#include <string>
#include <future>
struct X
{void foo(int,std::string const&);std::string bar(std::string const&);
};
X x;
auto f1=std::async(&X::foo,&x,42,"hello");    ⇽---  ①调用p->foo(42,"hello"),其中p的值是&x,即x的地址
auto f2=std::async(&X::bar,x,"goodbye");    ⇽---  ②调用tmpx.bar("goodbye"),其中tmpx是x的副本
struct Y
{double operator()(double);
};
Y y;
auto f3=std::async(Y(),3.141);    ⇽---  ③调用tmpy(3.141)。其中,由Y()生成一个匿名变量,传递给std::async(),进而发生移动构造。在std::async()内部产生对象tmpy,在tmpy上执行Y::operator()(3.141)
auto f4=std::async(std::ref(y),2.718);    ⇽---  ④调用y(2.718)
X baz(X&);
std::async(baz,std::ref(x));    ⇽---  ⑤调用baz(x)
class move_only
{public:move_only();move_only(move_only&&)move_only(move_only const&) = delete;move_only& operator=(move_only&&);move_only& operator=(move_only const&) = delete;void operator()();
};
auto f5=std::async(move_only());    ⇽---  ⑥调用tmp(),其中tmp等价于std::move (move_only()),它的产生过程与③相似

按默认情况下,std::async()的具体实现会自行决定——等待future时,是启动新线程,还是同步执行任务。大多数情况下,我们正希望如此。不过,我们还能够给std::async()补充一个参数,以指定采用哪种运行方式。参数的类型是std::launch,其值可以是std::launch::deferredstd::launch::async。前者指定在当前线程上延后调用任务函数,等到在future上调用了wait()get(),任务函数才会执行;后者指定必须另外开启专属的线程,在其上运行任务函数。该参数的值还可以是std::launch::deferred | std::launch:: async,表示由std::async()的实现自行选择运行方式。最后这项是参数的默认值。若延后调用任务函数,则任务函数有可能永远不会运行。举例如下。

auto f6=std::async(std::launch::async,Y(),1.2);    ⇽---  ①运行新线程auto f7=std::async(std::launch::deferred,baz,std::ref(x));    ⇽---  ②在wait()或get()内部运行任务函数
auto f8=std::async(    ⇽---  std::launch::deferred | std::launch::async,baz,std::ref(x));
auto f9=std::async(baz,std::ref(x));     ⇽---  ③交由实现自行选择运行方式
f7.wait();    ⇽---  ④前面②处的任务函数调用被延后,到这里才运行

std::future ---C++17 多线程相关推荐

  1. C++多线程std::async、std::future、std::packaged_task、std::promise

    std::async std::async用于创建异步任务,实际上就是创建一个线程执行相应任务,默认立即开始执行. std::async就是异步编程的高级封装,std::async的操作,其实相当于封 ...

  2. C++ 多线程:std::future

    概念 我们前面介绍的std::thread 是C++11中提供异步创建多线程的工具,只能是异步运行任务,却无法获取任务执行的结果,一般都是依靠全局对象,全局对象在多线程下是及其不安全的,为此标准库提供 ...

  3. C++多线程编程(3) 异步操作类 std::future std::promise std::async

    C++中提供了异步操作相关的类: 1. std::future: 异步结果的传输通道,可以很方便的获取线程函数的返回值. 在C++中,如果希望获取线程函数的返回值,就不能直接通过thread.join ...

  4. std::packaged_task() ---C++17 并发编程

    std::packaged_task() -C++17 并发编程 std::packaged_task<>连结了future对象与函数(或可调用对象). std::packaged_tas ...

  5. C++并发编程线程间共享数据std::future和sd::promise

    线程间共享数据 使用互斥锁实现线程间共享数据 为了避免死锁可以考虑std::lock()或者boost::shared_mutex 要尽量保护更少的数据 同步并发操作 C++标准库提供了一些工具 可以 ...

  6. std::future和std::promise和std::packaged_task

    std::future 其实future有两个兄弟,一个是std::future, 一个是它大哥std::shared_future.他们的区别就是std::future只支持移动语义,它所引用的共享 ...

  7. 条件变量 ---C++17 多线程

    条件变量 -C++17 多线程 C++标准库提供了条件变量的两种实现:std::condition_variable 和std::condition_variable_any.它们都在标准库的头文件& ...

  8. 共享锁和排它锁---C++17 多线程

    共享锁和排它锁-C++17 多线程 读写锁把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作.C++17开始,标准库提供了shared_mutex类(在这 ...

  9. C++库std::future

    std::future 介绍 成员函数 作用 使用场景 异步任务 并发控制 结果获取 用法示例 使用std::async关联异步任务 使用std::promise与std::future配合 结果获取 ...

最新文章

  1. 心电图心电轴怎么计算_浅谈心电图
  2. 模拟网页行为之工具篇二
  3. swift int转string_用Swift开发macOS程序,九、目录模块
  4. python机器学习案例系列教程——基于规则的分类器
  5. JAVA 设计模式 适配器模式
  6. 模块之序列化模块json
  7. 如何打开设置了密码的ZIP文件?
  8. 人人商城互动直播(与通信服务器连接失败)
  9. 零基础零起步,三周带你重塑《钢铁侠》之路
  10. 微信小程序picker地区选择器显示省市二级联动
  11. 计算机类sci查重,SCI科研写作:国自然标书查重方法
  12. loadrunner入门教程(11)--回放脚本
  13. 元宇宙黑马来袭 海姆达尔Heimdallr 开启链游新玩法
  14. Python读excel去重
  15. 使用Go爬豆瓣电影Top250 并写入数据库
  16. 虚拟光驱 daemon tools lite 4.4 下载 2011最新版
  17. 京东物流为什么能够成为抗疫奇兵?
  18. 【室内农业】温湿度测控,继电器控制加热器、加湿器、电风扇
  19. 将pcap文件处理成KDD99数据集格式
  20. am335x mysql_移植mysql到ARM(AM335x)

热门文章

  1. python的xpath用法介绍_python爬虫之xpath的基本使用详解
  2. csv文件怎么转成excel_Java读写excel,excel转成json写入磁盘文件
  3. java 有参数的构造函数如何注入_Spring5参考指南:依赖注入
  4. 横流式冷却塔计算风量_研讨丨卓展标准高效制冷机房技术之影响冷却塔效率的几个因素...
  5. apns java 证书_APNS推送服务证书制作 图文详解教程(新)
  6. 王道操作系统考研笔记——2.3.4 信号量机制
  7. flask 上传 excel 并导入mysql
  8. Linux下检测网络状态是否正常
  9. 不带缓存的I/O和标准(带缓存的)I/O
  10. React开发(231):常见手机号邮箱的正则