C++笔记之std::async的用法
C++笔记之std::async的用法
code review!
文章目录
- C++笔记之std::async的用法
- 1.概念
- 2.C++ 异步任务的使用示例 - 使用 std::async 和 std::future
- 3. std::launch::async 和 std::launch::deferred
- 4.如果需要真正的异步,请指定std::launch::async
1.概念
std::async 是 C++ 标准库中的一个函数,用于创建异步任务,允许在另一个线程中执行函数,并返回一个 std::future 对象,以便获取函数的结果。std::async 的一般用法如下:

#include <iostream>
#include <future>// 一个简单的函数,用于演示 std::async
int foo(int x, int y) {return x + y;
}int main() {// 使用 std::async 创建异步任务std::future<int> result = std::async(foo, 3, 4);// 等待异步任务完成并获取结果int sum = result.get();std::cout << "Sum: " << sum << std::endl;return 0;
}
上述示例中,std::async 接受一个函数(foo)和它的参数,并在后台创建一个新线程来执行该函数。函数执行完毕后,可以使用 std::future 对象的 get() 方法来获取函数的返回值。
以下是 std::async 的一些重要注意事项和用法:
-
返回值类型:
std::async返回一个std::future对象,可以用于获取异步任务的返回值。 -
默认策略:
std::async可以接受一个可选的策略参数,例如std::launch::async和std::launch::deferred,用于指定任务是立即在新线程中执行还是延迟执行。如果不提供策略,默认行为由实现决定。 -
异常处理:如果异步任务抛出异常,
std::future对象的get()方法会重新抛出该异常。因此,需要适当地处理异常,或者使用std::future的wait()和wait_for()方法来检查任务是否出现异常。 -
返回值的共享和移动语义:根据策略,
std::async可能共享或移动参数,因此要小心在异步任务中使用共享数据。 -
后台线程管理:
std::async会自动创建和管理后台线程,但不提供对线程的直接控制。如果需要更多的线程控制功能,可以考虑使用std::thread。 -
取消任务:C++标准库在
std::async中不提供直接的取消任务的机制,因此需要通过其他方式来实现任务的取消。
2.C++ 异步任务的使用示例 - 使用 std::async 和 std::future

运行

代码
#include <iostream>
#include <future>int main() {// 使用std::async创建一个异步任务,并返回一个std::future对象std::future<int> future_result = std::async(std::launch::async, []() {// 模拟一个耗时操作,返回一个结果std::this_thread::sleep_for(std::chrono::seconds(2));return 42;});std::cout << "Waiting for the future to become ready..." << std::endl;// 使用std::future::get()等待任务完成并获取结果int result = future_result.get();std::cout << "Async task result: " << result << std::endl;return 0;
}
3. std::launch::async 和 std::launch::deferred
std::launch::async 和 std::launch::deferred 是用于控制 std::async 函数的执行策略的标志,它们决定了异步任务的行为。这两个标志可以作为 std::launch 枚举类型的成员来使用。以下是它们的详细解释:
-
std::launch::async:- 当使用
std::launch::async标志调用std::async时,函数将在新的线程中立即执行,即使没有调用std::future对象的get()方法也会执行。 - 这意味着任务会异步执行,不会阻塞当前线程,而是在后台创建一个新线程来执行任务。
- 如果你希望任务尽快执行,并且可以与其他操作并发执行,可以选择此策略。
- 当使用
-
std::launch::deferred:- 当使用
std::launch::deferred标志调用std::async时,函数不会立即执行,而是等待调用std::future对象的get()方法时再执行。 - 这意味着任务会延迟执行,直到你真正需要结果为止。如果未调用
get(),任务可能根本不会执行。 - 这种策略适用于需要懒惰地计算结果的情况,以节省计算资源。
- 当使用
默认情况下,如果不指定策略,std::async 的行为由 C++ 标准库实现决定,可以是 std::launch::async 也可以是 std::launch::deferred,取决于具体实现。因此,为了明确指定策略,你可以使用以下方式:
std::future<int> result = std::async(std::launch::async, foo, 3, 4); // 强制使用 std::launch::asyncstd::future<int> result = std::async(std::launch::deferred, foo, 3, 4); // 强制使用 std::launch::deferred
需要注意的是,使用 std::launch::async 策略可能会导致并发执行的线程数增加,而使用 std::launch::deferred 策略可能会导致任务延迟执行,因此需要根据具体情况选择适当的策略。
下面是一个完整的比较 std::launch::async 和 std::launch::deferred 策略的示例程序:
#include <iostream>
#include <future>int foo(int x, int y) {std::cout << "foo is running in thread " << std::this_thread::get_id() << std::endl;return x + y;
}int main() {// 使用 std::launch::async 策略,任务会立即在新线程中执行std::cout << "Using std::launch::async:" << std::endl;std::future<int> async_result = std::async(std::launch::async, foo, 3, 4);// 使用 std::launch::deferred 策略,任务会延迟执行,直到调用 get() 方法std::cout << "Using std::launch::deferred:" << std::endl;std::future<int> deferred_result = std::async(std::launch::deferred, foo, 3, 4);// 主线程继续执行其他工作std::this_thread::sleep_for(std::chrono::seconds(2));// 获取 std::launch::async 的结果(可能已经执行完毕)int async_sum = async_result.get();std::cout << "Result from std::launch::async: " << async_sum << std::endl;// 获取 std::launch::deferred 的结果(现在才执行)int deferred_sum = deferred_result.get();std::cout << "Result from std::launch::deferred: " << deferred_sum << std::endl;return 0;
}
在这个示例中,我们首先使用 std::launch::async 和 std::launch::deferred 策略调用了 foo 函数。foo 函数会输出当前线程的标识符。然后,主线程休眠了2秒钟以模拟其他工作。
接着,我们分别调用 async_result.get() 和 deferred_result.get() 来获取两种策略下的结果。你会注意到,std::launch::async 的任务会立即执行(可能已经执行完毕),而 std::launch::deferred 的任务直到调用 get() 时才会执行。
这个示例演示了 std::launch::async 和 std::launch::deferred 的不同行为,以及如何使用它们来控制异步任务的执行方式。
4.如果需要真正的异步,请指定std::launch::async

相关文章:
C++笔记之std::async的用法
C笔记之std::async的用法 code review! 文章目录 C笔记之std::async的用法1.概念2.C 异步任务的使用示例 - 使用 std::async 和 std::future3. std::launch::async 和 std::launch::deferred4.如果需要真正的异步,请指定std::launch::async 1.概念 std::async 是 …...
OpenCV4(C++)—— 图像连通域的详细分析
文章目录 前言一、connectedComponents函数二、connectedComponentsWithStats函数 前言 图像连通域,其实就是图像分割的一种方法。它通过检测像素之间的连接关系和相似性来划分图像中的区域,以便进行后续处理。图像邻域和图像邻域分析就不介绍了&#x…...
Rule-Engine-Starter V1.0.0
一个轻量级的规则引擎、搜索引擎,让条件匹配简单、优雅。 GIT地址 https://gitcode.cosmoplat.com/15011240224/rule-engine-starter 介绍 Rule-Engine-Starter 是一个轻量级规则引擎,V1.0.0主要解决条件匹配问题。比如飞书文档,每个文档都…...
绘制X-Bar-S和X-Bar-R图,监测过程,计算CPK过程能力指数
X-Bar-S图和X-Bar-R图是统计质量控制中常用的两种控制图,用于监测过程的稳定性和一致性。它们的主要区别在于如何计算和呈现数据的变化以及所关注的问题类型。 X-Bar-S图(平均值与标准偏差图): X-Bar代表样本均值,S代表…...
【每日一句】只出现一次的数
文章目录 Tag题目来源题目解读解题思路方法一:位运算 其他语言Cpython3 写在最后 Tag 【位运算-异或和】【数组】【2023-10-14】 题目来源 136. 只出现一次的数字 题目解读 给你一个数组,找出数组中只出现一次的元素。题目保证仅有一个元素出现一次&a…...
GDB调试程序常用命令
编译文件 g -g -o test test.cpp(注意:GDB调试的前提是在编译时加上-g参数.) 启动gdb # 方法一 gdb test # 方法二 gdb file test 设置断点 tbreak:设置临时断点,仅在第一次触发后失效。 watch:设置观察点,监控变量的…...
C语言,求两个数的二进制表达中,有多少个位数不同
以前我的博客中写过一篇求二进制的1的个数的博客,里面用按位与1的方式来判断位数是否为一。 如代码所示: #include <stdio.h> int num(int n) {int a 0;int i 0;while (i < 32){a a (n & 1);n n >> 1;i;}return a; } int main…...
解决Win10电脑无线网卡的移动热点无法开启问题
一、目的 利用无线网卡连接网络,然后又用无线网卡通过移动热点分享该网络。 移动热点,简单地说,就是将台式机或笔记本的 Internet 连接转化成 WIFI 信号以供移动设备无线上网的功能,硬件前提是电脑须安装有无线网卡。 二、问题 …...
Spring framework Day10:JSR330注入注解
前言 JSR330是Java社区标准化进程(Java Community Process,简称JCP)中的一个规范,全名为"Dependency Injection for Java",即Java的依赖注入规范。它定义了一组注解和相关的规范,用于实现依赖注…...
Java开发中List数据量大,需要分片批次处理
在开发过程中可能会遇到需要处理的List数据量过大,可以选择分批处理的方式对大量数据进行处理。 1、使用 apache 的工具包 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><v…...
Apache Doris 2.0.2 版本正式发布!
峰会官网已上线,最新议程请关注:doris-summit.org.cn 点击报名 亲爱的社区小伙伴们,Apache Doris 2.0.2 版本已于 2023 年 10 月 6 日正式发布,该版本对多个功能进行了更新优化,旨在更好地满足用户的需求。有 92 位贡献…...
transformers架构实现
目录 架构代码如下 模型打印如下 架构代码如下 import numpy as np from torch.autograd import Variable import copy from torch import softmax import math import torch import torch.nn.functional as F import torch.nn as nn # 构建Embedding类来实现文本嵌入层 class…...
C++类型推导
这里对C的类型推导方式进行一次全面的总结。 C中有三种类型推导的方式,分别是模板、auto以及decltype()。以下分别介绍这三种方式的同异。 一 模板 假设有这样的函数模板和这样的调用: template<typename T> void f(ParamType param);f(expr);…...
Open3D(C++) SVD分解求两个点云的变换矩阵
目录 一、算法原理二、代码实现三、结果展示四、相关链接一、算法原理 计算两个点云的质心计算中心化向量计算协方差矩阵奇异值分解,求解旋转矩阵 R R R计算平移向量 t t...
rtmp htttp推流Windows桌面到srs进行播放
推流命令: ffmpeg -f gdigrab -framerate 30 -i desktop -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -f flv rtmp://xxx.xxx.xxxx.xx/live/livestream 后面是推流地址 推流后的播放地址为: http://xxxxxx:8080/live/livestream.flv 可以写一个…...
NSSCTF做题(9)
[GDOUCTF 2023]<ez_ze> 看见输入框而且有提示说是ssti注入 输入{{7*7}} 试试,发现报错 输入{%%}发现了是jinja2模板 找到关键函数 Python SSTI利用jinja过滤器进行Bypass ph0ebuss Blog 原理见这篇文章,这里直接给出payload {%set ninedict(aaa…...
【09】基础知识:React组件的生命周期
组件从创建到死亡它会经历一些特定的阶段。 React 组件中包含一系列勾子函数(生命周期回调函数 <> 生命周期钩子函数 <> 生命周期函数 <> 生命周期钩子),会在特定的时刻调用。 我们在定义组件时,会在特定的生…...
Pytorch之ConvNeXt图像分类
文章目录 前言一、ConvNeXt设计决策1.设计方案2.Training Techniques3.Macro Design🥇Changing stage compute ratio🥈Change stem to "Patchify" 4.ResNeXt-ify5. Inverted Bottleneck6.Large Kernel Size7.Micro Design✨Replacing ReLU wit…...
Linux系统编程:makefile以及文件系统编程
增量编译概念 首先回顾一下我们之前写的各种gcc指令用来执行程序: 可以看见非常繁琐,两个文件就要写这么多,那要是成百上千岂不完蛋。 所以为了简化工作量,很自然的想到了将这些命令放在一起使用脚本文件来一键执行,…...
《动手学深度学习 Pytorch版》 8.5 循环神经网络的从零开始实现
%matplotlib inline import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, vocab d2l.load_data_time_machine(batch_size, num_steps) # 仍然使用时间机器数据集8.…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
