C++ 异步编程:std::async、std::future、std::packaged_task 和 std::promise
C++ 异步编程:std::async
、std::future
、std::packaged_task
和 std::promise
在现代 C++ 编程中,异步编程已经成为一种常见的模式。利用 C++11 引入的标准库组件 std::async
、std::future
、std::packaged_task
和 std::promise
,我们可以更方便地处理多线程任务。本文将介绍这些组件的基本用法及其应用场景,帮助你理解如何利用这些工具实现高效的异步编程。
1. std::future
和 std::promise
std::future
std::future
是一种用于获取异步计算结果的机制。它提供了一个等待异步任务完成并获取结果的方法。std::future
对象通过与 std::promise
结合使用,允许线程安全地获取异步操作的结果或异常。
基本用法:
#include <iostream>
#include <thread>
#include <future>void async_task(std::promise<int>& prom) {std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作prom.set_value(42); // 设置计算结果
}int main() {std::promise<int> prom;std::future<int> fut = prom.get_future();std::thread t(async_task, std::ref(prom)); // 使用 std::ref 传递 promise 的引用t.detach(); // 线程分离,允许在主线程中继续执行int result = fut.get(); // 等待异步任务完成并获取结果std::cout << "Result: " << result << std::endl;return 0;
}
解释:
std::promise<int>
创建一个promise
对象,用于设置值。std::future<int> fut = prom.get_future();
从promise
获取future
对象。- 在异步线程中,调用
prom.set_value(42);
设置结果。 fut.get();
阻塞当前线程,直到结果可用。
std::promise
std::promise
用于在异步操作中设置结果。它与 std::future
结合使用,以便从线程中传递结果或异常。std::promise
对象只能被设置一次,设置多次会引发异常。
基本用法:
#include <iostream>
#include <thread>
#include <future>void async_task(std::promise<int> prom) {prom.set_value(42); // 设置计算结果
}int main() {std::promise<int> prom;std::future<int> fut = prom.get_future();std::thread t(async_task, std::move(prom)); // 使用 std::move 转移 promiset.join(); // 等待线程完成int result = fut.get(); // 获取异步任务的结果(会阻塞直到结果可用)std::cout << "Result: " << result << std::endl;return 0;
}
解释:
std::promise<int> prom;
创建promise
对象。std::future<int> fut = prom.get_future();
获取future
对象。- 在异步线程中,通过
prom.set_value(42);
设置结果。 fut.get();
获取结果并阻塞当前线程。
2. std::packaged_task
std::packaged_task
是一个可调用对象,用于将任务的结果与 std::future
绑定。它允许你将一个普通的函数或函数对象封装为一个异步任务,并从中获取结果。
基本用法:
#include <iostream>
#include <thread>
#include <future>int long_computation(int x) {std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作return x * x;
}int main() {std::packaged_task<int(int)> task(long_computation); // 创建任务std::future<int> fut = task.get_future(); // 获取 future 对象std::thread t(std::move(task), 10); // 使用 std::move 转移任务,并传递参数t.join(); // 等待线程完成int result = fut.get(); // 获取异步任务的结果(会阻塞直到结果可用)std::cout << "Result: " << result << std::endl;return 0;
}
解释:
std::packaged_task<int(int)> task(long_computation);
创建一个任务对象,封装long_computation
函数。std::future<int> fut = task.get_future();
获取与任务关联的future
对象。std::thread t(std::move(task), 10);
将任务移动到线程中,并传递参数。fut.get();
获取任务结果。
3. std::async
std::async
是一种更高层次的异步操作工具,它可以在后台线程中异步执行函数,并返回一个 std::future
对象,用于获取结果。它比手动创建线程更简单。
基本用法:
#include <iostream>
#include <future>
#include <chrono>int long_computation(int x) {std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作return x * x;
}int main() {std::future<int> fut = std::async(std::launch::async, long_computation, 10); // 异步执行// 可以在这里做其他事情std::cout << "Doing other things while waiting for the result..." << std::endl;int result = fut.get(); // 获取异步任务的结果(会阻塞直到结果可用)std::cout << "Result: " << result << std::endl;return 0;
}
解释:
std::async(std::launch::async, long_computation, 10);
异步执行long_computation
函数,并传递参数。fut.get();
获取结果并阻塞当前线程,直到结果可用。
总结
std::promise
用于设置异步操作的结果或异常。std::future
用于获取异步操作的结果或异常。std::packaged_task
封装函数为任务,并与std::future
结合使用。std::async
简化异步任务的创建和管理,自动处理线程和任务。
通过理解和使用这些 C++ 标准库组件,你可以更高效地进行异步编程,管理复杂的任务和线程操作。
相关文章:
C++ 异步编程:std::async、std::future、std::packaged_task 和 std::promise
C 异步编程:std::async、std::future、std::packaged_task 和 std::promise 在现代 C 编程中,异步编程已经成为一种常见的模式。利用 C11 引入的标准库组件 std::async、std::future、std::packaged_task 和 std::promise,我们可以更方便地处…...
OD C卷 - 石头剪刀布游戏
石头剪刀布游戏 (100) 剪刀石头布游戏,A-石头、B-剪刀、C-布游戏规则: 胜负规则,A>B; B>C; C>A;当本场次中有且仅有一种出拳形状优于其他出拳形状,则该形状的玩家是胜利者,否则认为是…...

关于k8s集群中kubectl的陈述式资源管理
1、k8s集群资源管理方式分类 (1)陈述式资源管理方式:增删查比较方便,但是改非常不方便 使用一条kubectl命令和参数选项来实现资源对象管理操作 (2)声明式资源管理方式:yaml文件管理 使用yam…...

XML 学习笔记
简介: (1)XML:可扩展性标记语言,用于传输和存储数据,而不是展示数据,是W3C 推举的数据传输格式。 XML的标签必须自定义,但是在写标签名的时候一定要有含义。 XML 只能有一个根节点…...

MongoDB未授权访问漏洞
2.MongoDB未授权访问漏洞 mongodb数据库是由C编写,主要是为了提供web应可用扩展的一种高性能数据库。开启MongoDB服务时不添加任何参数时,默认是没有权限验证的,登录的用户可以通过默认端口无需密码对数据库任意操作(增、删、改、查高危动作)而且可以远程访问数据库…...

数据安全、信息安全、网络安全区别与联系
关键字: 信息安全 数据安全 网络安全 [导读] 让人更好理解 “数据安全”、“信息安全”、“网络安全” 三者间的区别与联系了,我们汇总了官方机构给这三者的定义,并且网友也给出了自己的看法,一起来看看。 在 “互联网 ” 被广…...

Jenkins未授权访问漏洞 *
漏洞复现 步骤一:使用以下fofa语法进行产品搜索.... port"8080" && app"JENKINS" && title"Dashboard [Jenkins]" 步骤二:在打开的URL中...点击Manage Jenkins --> Scritp Console在执行以下命令..…...
【爬虫原理】
《爬虫》 1、爬虫的概念 概念:(spider,网络蜘蛛)通过互联网上一个个的网络节点,进行数据的提取、整合以及存储 分类: 通用爬虫(了解) 主要用于搜索引擎(百度、…...

计算机组成原理 —— 指令流水线的基本概念
计算机组成原理 —— 指令流水线的基本概念 串行执行(Serial Execution)串行执行的特点串行执行的局限性串行执行的应用场景 并行执行定义基本原理五段式指令流水线优点缺点 流水线的性能指标示例计算 我们来了解一下指令流水线: 首先在这之…...
Python爬虫技术 第31节 持续集成和自动化部署
持续集成和自动化部署 Git版本控制 Git 是一个非常流行的分布式版本控制系统,用于跟踪对项目文件的修改。对于爬虫项目来说,使用Git可以帮助你管理代码的不同版本,协同开发,并且可以在出现问题时回滚到之前的版本。 基本操作&a…...
数据结构(C语言版)(第2版)课后习题答案
数据结构(C语言版)(第2版)课后习题答案 李冬梅 2015.3 目 录 第 1 章 绪论 1 第 2 章 线性表 5 第 3 章 栈和队列 13 第 4 章 串、数组和广义表 26 第 5 章 树和二叉树 33 第 6 章 图 43 第 7 章 查找 54 第 8 章 排序 65…...
打开轮盘锁问题(LeetCode)的分析总结及进一步提问
打开轮盘锁问题分析总结,及进一步提问:请给出一组最小步数下的号码序列组合 题目描述 你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由…...

python——joblib进行缓存记忆化-对计算结果缓存
问题场景 在前端多选框需要选取多个数据进行后端计算。 传入后端是多个数据包的对应路径。 这些数据包需要按一定顺序运行,通过一个Bag(path).get_start_time() 可以获得一个float时间值进行排序,但由于数据包的特性,这一操作很占用性能和时…...

Linux文件管理
系列文章目录 提示:仅用于个人学习,进行查漏补缺。 1.Linux介绍、目录结构、文件基本属性、Shell 2.Linux常用命令 3.Linux文件管理 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1…...

《Unity3D网络游戏实战》学习与实践--制作一款大乱斗游戏
角色类 基类Base Human是基础的角色类,它处理“操控角色”和“同步角色”的一些共有功能;CtrlHuman类代表“操控角色”,它在BaseHuman类的基础上处理鼠标操控功能;SyncHuman类是“同步角色”类,它也继承自BaseHuman&…...
文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑源-荷不确定性的省间电力现货市场潮流风险概率评估》
本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…...
Pinterest 选择采用 TiDB
原文来源: https://tidb.net/blog/9f000c95 作者:Pinterest 公司高级软件工程师 Alberto Ordonez Pereira ;高级工程经理 Lianghong Xu 声明:本文转载于 https://medium.com/pinterest-engineering/tidb-adoption-…...
【Python】 如何用 Docker 打包一个 Python 脚本
这是我父亲 日记里的文字 这是他的生命 留下留下来的散文诗 几十年后 我看着泪流不止 可我的父亲已经 老得像一个影子 🎵 许飞《父亲写的散文诗》 如何用 Docker 打包一个 Python 脚本 Docker 是一个开源的容器化平台,允许开发者将…...

从“幕后”到“台前”:一文读懂API经济如何促进企业的创新与增长
API(Application Programming Interface,应用程序接口)指一组定义软件程序如何与其他组件、服务或系统交互的规范。在传统的IT语境中,API往往更多承担前后端对接或应用系统间内部集成渠道的作用。但在当今大数据与智能化的时代&am…...

解锁PDF新姿势:2024年PDF转图片工具精选
随着数字化办公的普及和文档处理需求的日益增长,PDF转图片工具已成为日常工作中不可或缺的一部分。这些工具不仅帮助用户轻松地将PDF文件转换为图片格式,还提供了丰富的编辑、转换和批量处理功能,极大地提高了工作效率。 1.福昕PDF转换大师&…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...