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.…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...