当前位置: 首页 > news >正文

C++ 异步编程:std::async、std::future、std::packaged_task 和 std::promise

C++ 异步编程:std::asyncstd::futurestd::packaged_task 和 std::promise

在现代 C++ 编程中,异步编程已经成为一种常见的模式。利用 C++11 引入的标准库组件 std::asyncstd::futurestd::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 异步编程&#xff1a;std::async、std::future、std::packaged_task 和 std::promise 在现代 C 编程中&#xff0c;异步编程已经成为一种常见的模式。利用 C11 引入的标准库组件 std::async、std::future、std::packaged_task 和 std::promise&#xff0c;我们可以更方便地处…...

OD C卷 - 石头剪刀布游戏

石头剪刀布游戏 &#xff08;100&#xff09; 剪刀石头布游戏&#xff0c;A-石头、B-剪刀、C-布游戏规则&#xff1a; 胜负规则&#xff0c;A>B; B>C; C>A;当本场次中有且仅有一种出拳形状优于其他出拳形状&#xff0c;则该形状的玩家是胜利者&#xff0c;否则认为是…...

关于k8s集群中kubectl的陈述式资源管理

1、k8s集群资源管理方式分类 &#xff08;1&#xff09;陈述式资源管理方式&#xff1a;增删查比较方便&#xff0c;但是改非常不方便 使用一条kubectl命令和参数选项来实现资源对象管理操作 &#xff08;2&#xff09;声明式资源管理方式&#xff1a;yaml文件管理 使用yam…...

XML 学习笔记

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

MongoDB未授权访问漏洞

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

数据安全、信息安全、网络安全区别与联系

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

Jenkins未授权访问漏洞 *

漏洞复现 步骤一&#xff1a;使用以下fofa语法进行产品搜索.... port"8080" && app"JENKINS" && title"Dashboard [Jenkins]" 步骤二&#xff1a;在打开的URL中...点击Manage Jenkins --> Scritp Console在执行以下命令..…...

【爬虫原理】

《爬虫》 1、爬虫的概念 ​ 概念&#xff1a;&#xff08;spider&#xff0c;网络蜘蛛&#xff09;通过互联网上一个个的网络节点&#xff0c;进行数据的提取、整合以及存储 分类&#xff1a; 通用爬虫&#xff08;了解&#xff09; ​ 主要用于搜索引擎&#xff08;百度、…...

计算机组成原理 —— 指令流水线的基本概念

计算机组成原理 —— 指令流水线的基本概念 串行执行&#xff08;Serial Execution&#xff09;串行执行的特点串行执行的局限性串行执行的应用场景 并行执行定义基本原理五段式指令流水线优点缺点 流水线的性能指标示例计算 我们来了解一下指令流水线&#xff1a; 首先在这之…...

Python爬虫技术 第31节 持续集成和自动化部署

持续集成和自动化部署 Git版本控制 Git 是一个非常流行的分布式版本控制系统&#xff0c;用于跟踪对项目文件的修改。对于爬虫项目来说&#xff0c;使用Git可以帮助你管理代码的不同版本&#xff0c;协同开发&#xff0c;并且可以在出现问题时回滚到之前的版本。 基本操作&a…...

数据结构(C语言版)(第2版)课后习题答案

数据结构&#xff08;C语言版&#xff09;&#xff08;第2版&#xff09;课后习题答案 李冬梅 2015.3 目 录 第 1 章 绪论 1 第 2 章 线性表 5 第 3 章 栈和队列 13 第 4 章 串、数组和广义表 26 第 5 章 树和二叉树 33 第 6 章 图 43 第 7 章 查找 54 第 8 章 排序 65…...

打开轮盘锁问题(LeetCode)的分析总结及进一步提问

打开轮盘锁问题分析总结&#xff0c;及进一步提问&#xff1a;请给出一组最小步数下的号码序列组合 题目描述 你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字&#xff1a; ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由…...

python——joblib进行缓存记忆化-对计算结果缓存

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

Linux文件管理

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

《Unity3D网络游戏实战》学习与实践--制作一款大乱斗游戏

角色类 基类Base Human是基础的角色类&#xff0c;它处理“操控角色”和“同步角色”的一些共有功能&#xff1b;CtrlHuman类代表“操控角色”​&#xff0c;它在BaseHuman类的基础上处理鼠标操控功能&#xff1b;SyncHuman类是“同步角色”类&#xff0c;它也继承自BaseHuman&…...

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑源-荷不确定性的省间电力现货市场潮流风险概率评估》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…...

Pinterest 选择采用 TiDB

原文来源&#xff1a; https://tidb.net/blog/9f000c95 作者&#xff1a;Pinterest 公司高级软件工程师 Alberto Ordonez Pereira &#xff1b;高级工程经理 Lianghong Xu 声明&#xff1a;本文转载于 https://medium.com/pinterest-engineering/tidb-adoption-…...

【Python】 如何用 Docker 打包一个 Python 脚本

这是我父亲 日记里的文字 这是他的生命 留下留下来的散文诗 几十年后 我看着泪流不止 可我的父亲已经 老得像一个影子 &#x1f3b5; 许飞《父亲写的散文诗》 如何用 Docker 打包一个 Python 脚本 Docker 是一个开源的容器化平台&#xff0c;允许开发者将…...

从“幕后”到“台前”:一文读懂API经济如何促进企业的创新与增长

API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;指一组定义软件程序如何与其他组件、服务或系统交互的规范。在传统的IT语境中&#xff0c;API往往更多承担前后端对接或应用系统间内部集成渠道的作用。但在当今大数据与智能化的时代&am…...

解锁PDF新姿势:2024年PDF转图片工具精选

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

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...