C++ 异步编程中:future与promise、packaged_task、async

原文链接:C++ 异步编程之future与promise、async、packaged_task_std::promise和std::future异步发送-CSDN博客

1、std::future
std::future类模板来关联线程运行的函数和函数的返回结果,这种获取结果的方式是异步的

std::future 通常由某个 Provider 创建,你可以把 Provider 想象成一个异步任务的提供者,
Provider 在某个线程中设置共享状态的值,与该共享状态相关联的 std::future 对象调用 get(通常在另外一个线程中) 获取该值,
如果共享状态的标志不为 ready,则调用 std::future::get 会阻塞当前的调用者,直到 Provider 设置了共享状态的值(此时共享状态的标志变为 ready),
std::future::get 返回异步任务的值或异常(如果发生了异常)。

2、std::promise
std::promise类型模板提供“设置异步结果”的方法,
这样其他线程就可以通过std::future实例来“读取”该结果。
std::promise和std::future合作共同实现了多线程间通信。

通过调用std::promise的get_future函数,可以将该共享状态与std::future对象关联。
调用get_future之后,两个对象共享相同的共享状态:
std::promise对象是异步提供程序(asynchronous provider),应在某个时刻为共享状态设置一个值。
std::future对象是个异步返回对象,可以检索共享状态的值,并在必要时等待其准备就绪。
 需要注意的是:set_value只能被调用一次,多次调用会抛出std::future_error异常。
事实上std::promise::set_xxx函数会改变std::promise的状态为ready,
再次调用时发现状态已是reday了,则抛出异常。


3、std::packaged_task
std::packaged_task是一个模板类,它允许传入一个函数或其他可调用对象,
并将函数计算的结果作为异步结果传递给std::future,包括函数运行时产生的异常。

std::packaged_task、std::promise作用:

std::packaged_task使用的一般步骤:

1.创建了一个std::packaged_task对象,并封装线程入口函数compute函数。
2.获取与任务关联的std::future对象。
3.在一个新的线程中执行任务。
4.等待并获取结果。

#include <iostream>
#include <future>
#include <thread>
#include <chrono>

int compute(int a, int b) {
    std::this_thread::sleep_for(std::chrono::seconds(5)); // 模拟长时间计算
    return a + b;
}

void task1() {
    //1.创建了一个std::packaged_task对象,并封装了线程函数compute函数
    std::packaged_task<int(int, int)> task(compute);
    //2.获取与任务关联的std::future对象
    std::future<int> result = task.get_future();
    //3.在一个新的线程t中执行任务
    std::thread t(std::move(task), 5, 4);

    std::cout << "Waiting for result..." << std::endl;
    //4.使用与任务关联的std::future对象的get()方法,异步获取结果
    std::cout << "Result: " << result.get() << std::endl;
    
    t.join();
}

int main() {
    task1();
    return 0;
}

4、c++11提供了异步接口std::async
c++11提供了异步接口std::async,通过这个异步接口可以很方便的获取线程函数的执行结果。
std::async会自动创建一个线程去调用线程函数,它返回一个std::future,这个future中存储了线程函数返回的结果

当有线程调用了这个future对象的wait()和get()成员函数,则该任务会同步运行;

std::async是一个函数而非类模板,其函数执行完后的返回值绑定给std::futrue对象;
async(launch policy, Callable&& func, Args&& ... args);
std::launch policy是启动策略,它控制std::async的异步行为,
我们可以用“3种不同的启动策略”来创建std::async:
    std::launch::async参数:保证异步行为,即传递函数将在单独的线程中执行;
    std::launch::deferred参数:当其他线程调用get()/wait()来访问共享状态时,将调用非异步行为;
    std::launch::async | std::launch::deferred参数:是默认行为(可省略)。有了这个启动策略,它可以异步运行或不运行,这取决于系统的负载。

std::async允许通过添加额外的调用参数,向函数传递额外的参数。
第一个参数是指向成员函数的指针,
第二个参数提供这个函数成员类的具体对象(是通过指针,也可以包装在std::ref中),剩余的参数可作为函数的参数传入。
    否则,第二个和随后的参数将作为函数的参数,或作为指定可调用对象的第一个参数。
auto f1= std::async(&X::foo,&x, 42, "hello");  // 调用p->foo(42, "hello"),p是指向x的指针
auto f2= std::async(&X::bar, x, "goodbye");  // 调用tmpx.bar("goodbye"), tmpx是x的拷贝副本
std::async 的返回值(std::future)在析构函数里会等待任务完成;
    
std::async意义:
    在已经有了td::future、std::promise和std::packaged_task的情况下,实现异步或多线程间通信,
可能觉得已经足够了,真的还要一个std::async来凑热闹吗??
=》
是std::async是为了让用户的少费点脑子的,它让这三个对象默契的工作。
大概的工作过程是这样的:std::async先将异步操作用std::packaged_task包装起来,
然后将异步操作的结果放到std::promise中,这个过程就是创造未来的过程。
外面再通过future.get/wait来获取这个未来的结果。
=》std::async真的是来帮忙的,你不用再想到底该怎么用std::future、std::promise和 std::packaged_task了,
std::async已经帮你搞定一切了!这就是我们前面说的,std::async类似封装了thread和packged_task的功能。
使得我们使用起来更加方便简单。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/883914.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

unity 打包安卓 RenderTexture显示红色

1、ColorFarmat&#xff1a; 每个图形卡可能并不支持跨格式的所有用法。使用 SystemInfo.IsFormatSupported 可以检查图形卡支持的用法。 None未指定格式。R8G8B8A8_UNorm一种四分量、32 位无符号归一化格式&#xff0c;在字节 0 中具有 8 位 R 分量&#xff0c;在字节 1 中具…

Java面试篇基础部分-ReentrantLock详解(二)

Lock 接口的主要方法 void lock():给对象加锁,如果锁没有被其他线程使用,则当前线程获取到这个锁;如果锁正在被其他线程持有,则将禁用当前线程,直到当前线程获取到锁。boolean tryLock():试图给对象进行加锁操作,如果锁没有被其他线程使用,则将获取到这个锁并且返回tr…

Linux ubuntu debian系统安装UFW防火墙图形化工具GUFW

GUFW是UFW的图形化前端&#xff0c;可以通过以下命令安装&#xff1a; sudo apt install gufw安装成功后&#xff0c;可以通过应用程序菜单启动GUFW&#xff0c;在图形界面中&#xff0c;可以方便地添加、修改和删除规则&#xff0c;查看状态和日志。

【入门01】arcgis api 4.x 创建地图、添加图层、添加指北针、比例尺、图例、卷帘、图层控制、家控件(附完整源码)

1.效果 2.代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title></title><link rel"s…

CDGA|数据治理:策略与价值的深度融合

在当今这个数据驱动的时代&#xff0c;企业数据治理的重要性日益凸显。数据不仅是企业的核心资产&#xff0c;更是驱动业务决策、优化运营流程、创新产品服务的关键力量。然而&#xff0c;要让数据治理真正发挥价值&#xff0c;企业需要采取一系列策略来确保数据的准确性、完整…

C++之二叉搜索

1.二叉搜索树的概念 二叉搜索树又称为二叉排序树&#xff0c;它有以下的特点。 1.如果它的左子树不为空&#xff0c;则左子树上所以结点的值都小于等于根结点的值 2.如果它的右子树不为空&#xff0c;则右子树上所有结点都大于等于根结点的值 3.它的左右子树也分别为二叉搜…

【C++笔试强训】如何成为算法糕手Day3

​ 学习编程就得循环渐进&#xff0c;扎实基础&#xff0c;勿在浮沙筑高台 循环渐进Forward-CSDN博客 目录 循环渐进Forward-CSDN博客 第一题&#xff1a;除2&#xff01; 第二题&#xff1a;dd爱框框 第三题&#xff1a;简写单词 第一题&#xff1a;除2&#xff01; 牛客网…

数据保护从现在开始:如何抵御 .[RestoreBackup@cock.li].SRC 勒索病毒

导言 勒索病毒是一种不断演变的网络威胁&#xff0c;.[RestoreBackupcock.li].SRC、[chewbaccacock.li].SRC勒索病毒便是其中一种新型的攻击手段。该病毒通过加密用户文件并要求支付赎金来恢复访问&#xff0c;给个人和企业带来了严重的安全风险和经济损失。本文91数据恢复将探…

25 基于51单片机的温度电流电压检测系统(压力、电压、温度、电流、LCD1602)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;通过DS18B20检测温度&#xff0c;滑动变阻器连接数模转换器模拟电流、电压&#xff0c;通过LCD1602显示&#xff0c;程序里设置温度阈值为40&#xff0c;电流阈值为60&am…

新版torch_geometric不存在uniform、maybe_num_nodes函数问题(Prune4ED论文报错解决)

这是在复现论文“Towards accurate subgraph similarity computation via neural graph pruning”时遇到的报错。 ImportError: cannot import name uniform from torch_geometric.nn.pool.topk_pool 一、报错原因 论文作者使用的是2.1.0版本的torch_geometric。而我安装了2.…

[vulnhub] Jarbas-Jenkins

靶机链接 https://www.vulnhub.com/entry/jarbas-1,232/ 主机发现端口扫描 扫描网段存活主机&#xff0c;因为主机是我最后添加的&#xff0c;所以靶机地址是135的 nmap -sP 192.168.75.0/24 // Starting Nmap 7.93 ( https://nmap.org ) at 2024-09-21 14:03 CST Nmap scan…

linux信号| 学习信号三步走 | 学习信号需要打通哪些知识脉络?

前言: 本节内容主要讲解linux下信号的预备知识以及信号的概念&#xff0c; 信号部分我们将会分为几个阶段进行讲解&#xff1a;信号的概念&#xff0c; 信号的产生&#xff0c; 信号的保存。本节主要讲解信号 ps:本节内容适合学习了进程相关概念的友友们进行观看哦 目录 什么是…

教练车一键启动应用‌案例

教练车一键启动应用‌主要提供了便捷的车辆启动方式&#xff0c;通过一个按钮实现车辆的启动和熄火&#xff0c;简化了传统的打火过程。这种智能配置不仅提升了车辆的科技感&#xff0c;还增加了市场竞争力。一键启动系统可以在原车钥匙锁头位置安装&#xff0c;也可以作为独立…

基于JAVA+SpringBoot+Vue的疫苗发布和接种预约系统

基于JAVASpringBootVue的疫苗发布和接种预约系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f3…

3D 模型GLTF、GLB格式文件介绍使用;FBX格式

一、GLTF、GLB介绍 GLTF&#xff08;GL Transmission Format&#xff09;和 GLB&#xff08;GL Binary&#xff09;是用于在 Web 和各种应用程序中传输和加载 3D 场景和模型的开放标准格式。它们由 Khronos Group 开发&#xff0c;旨在提供一种高效、可扩展且易于使用的 3D 内…

URI和URL的区别

1: 将 URI 转换为 URL import java.net.URI; import java.net.URL;public class UriToUrlExample {public static void main(String[] args) {// 创建一个 URI 对象URI uri = new URI("http://example.com/path/to/resource");// 将 URI 转换为 URLtry {URL url = u…

推荐一款PS VR2电脑PC适配器 / 转接板方案

一、引言 随着虚拟现实技术的不断发展&#xff0c;PS VR2 为用户带来了沉浸式的游戏和娱乐体验。然而&#xff0c;为了让 PS VR2 能够与电脑连接&#xff0c;充分发挥其性能并拓展使用场景&#xff0c;需要开发一款电脑适配器 / 转接板。本技术文档方案旨在详细阐述该适配器 / …

【伺服】Servo入坑学习记录①

前言 这是一个自我摸索的过程&#xff0c;如果有什么良好的、或严厉的批评和建议&#xff0c;恳请指教&#xff0c; 万分感谢经典控制理论中&#xff0c;有几个重要的概念和工具&#xff0c;用于分析和设计控制系统。以下是对 传递函数、伯德图、奈奎斯特图、稳定裕度 和 带宽 …

缓存装饰器@cached_property

这个装饰器好像在好多包里都有&#xff0c;我在阅读源码的过程中&#xff0c;transformers.utils也有这个。查阅资料&#xff0c;大体上了解了它的用法。参考&#xff1a;[python]cached_property缓存装饰器 - faithfu - 博客园 这个装饰器用在类里面的某个方法前面&#xff0…

传奇微端黑屏不更新地图?传奇微端架设教程——GOM引擎

登录器和网站配置好后&#xff0c;我们进入游戏后会发现是黑屏的&#xff0c;更新不了地图和NPC这些&#xff0c;因为还没有做微端&#xff0c;会黑屏也是正常的。有些老G做了微端但是还是黑屏&#xff0c;就可能是你的微端架设出现了问题&#xff0c;可以参考以下教程。 gom引…