异步编程详解

news2024/9/19 10:41:57

1.什么是async
std::async:是一个函数模板,用于启动一个异步任务。它接受一个可调用的对象(如函数、Lambda表达式、函数对象)作为参数,并在一个单独的线程上异步执行对象。std::async自动管理异步任务的生命周期,并返回一个std::future对象,该对象用于获取异步操作的结果。
2.什么是future
std::future:是一个函数模板,用于表示异步操作的结果。它允许开发者在将来的某个时刻查询异步操作的状态、等待操作完成或获取操作的结果。通常,std::future对象不是直接创建的,而是与std::async、std::packaged_task或std::promise配合使用。
它的主要函数:
①.get()
作用:等待异步操作完成,并获取其结果。如果异步操作尚未完成,调用get()的线程将被阻塞,直到操作完成。一旦调用get(),它将返回异步操作的结果,并且将std::future对象将不再与任何共享状态相关联(即它将变为无效状态)
注意:get()方法只能被调用一次。如果多次尝试调用get(),将抛出std::future_error异常。
②.wait()
作用:等待异步操作完成,但不获取结果。调用wait()会阻塞当前线程,直到异步操作完成。与get()不同,调用wait()后,std::future对象仍然有效,可以继续使用get()来获取结果。
③.wait_for()
等待异步操作完成,但只等待指定的时间段。如果异步操作在该时间段内完成,wait_for()将返回std::future_status::ready。如果操作未完成但时间已过,返回std::future_status::timeout,如果异步操作尚未启动(如使用std::launched::deferred策略),则返回std::future_status::deferred。
参数:接收一个用于表示等待时间的时间段,如std::chrono::millisecond(30),std::chrono::seconds(30)。std::chrono为c++时间库。

#include<iostream>
#include<thread>
#include<future>
using namespace std;
int myfun(int a,int b) {
	return a + b;
}

int main() {
	future<int>myf = async(launch::deferred, myfun, 20, 30);
	myf.wait();
	cout << "myf==" << myf.get() << endl;
	/*thread t(myfun, 10, 20);
	t.join();*/
	return 0;
}

3.三种启动策略
①.launch::async
行为:该策略指示std::async必须异步地执行任务,即必须在一个新的线程中启动任务,这意味着调用syd::async之后,任务将立即在新线程中开始执行,而调用线程可以继续执行其他任务。
适用场景:当你需要确保任务在单独的线程中执行,并且不希望它阻塞当前线程时,应使用此策略。
②.launch::deferred
行为:该策略指示std::deferred可以延迟任务的执行,直到调用std::future::get()或std::future::wait()方法时,任务才在当前线程中执行。如果任务从未被查询(即没有调用get()和wait()),则任务可能永远不会执行。
适用场景:当你希望仅在需要结果时才执行任务,或者当任务执行不会阻塞其他重要操作时,此策略可能会很有用。然而需要注意的是,使用此策略可能会引起潜在的并发问题,因为任务可能在查询结果时才执行。
③.launch::async|launch::deferred(默认策略)
行为:这个策略是std::launch::async和std::launch::deferred的组合,但它并不保证具体的执行方式。实际执行方式取决于实现(如编译器和库)以及系统资源。在某些情况下,任务可能会异步执行。在其他情况下,他可能会被延迟执行。
应用场景:由于此策略的行为是不确定的,因此它可能不适用于需要精确控制任务执行方式的场景。然而,作为默认策略,他提供了一种灵活的方式来启动异步任务,同时允许实现根据当前系统状况进行优化。
4.promise

#include<iostream>
#include<thread>
#include<future>
using namespace std;
//promise的用法,在一个线程中设置值,在另一个线程中获取值
void async_task(std::promise<int>prom) {
	std::this_thread::sleep_for(std::chrono::seconds(1));//模拟异步操作
	prom.set_value(42);
}


int main() {
	std::promise<int>prom;
	std::future<int>fut = prom.get_future();//获取与promise关联的future
	
	std::thread t(async_task, std::move(prom));//启动异步任务,并将promise传给它

    //prom可以移动但不可以复制,也可以写成 thread t(async_task,&prom) async_task的参数为(std::promise<int>*prom)

	std::cout << "The result is " << fut.get() << std::endl;//在主线程中等待异步操作完成并获取结果
	t.join();
	return 0;
}

在这里插入图片描述
get_future():返回一个std::future对象,该对象与std::promise对象共享状态。你可以通过这个std::future对象来检索异步操作的结果。
set_value(T_value):设置异步操作的结果。调用此方法后,与std::promise关联的std::future对象将变为fulfilled状态,并且可以通过std::future::get()来检索结果。
set_exception(std::exception_ptr p):设置异步操作中抛出的异常。调用此方法后,与std::promise关联的std::future对象将变为rejected状态,并且可以通过调用std::future::get()来重新抛出异常。

注意事项:
①.std::promise的生命周期:确保std::promise对象在std:;future对象需要它之前保持有效。一旦std::promise对象被销毁,任何尝试通过std::future对象访问其结果的操作都将失败。
②.线程安全:std::promise的set_value和set_exception是线程安全的,但应该避免在多个线程同时调用它们
③.std::move的使用,在将std::promise对象传递给线程函数时,通常使用std::move来避免不必要的复制。这是因为std::promise对象通常包含非托管资源(如共享状态),复制它们可能是昂贵的或不必要的复制。

5.packaged_task
创建packaged_task对象时,需要传递一个可调用对象(如函数、lambda表达式),这个对象被封装在packaged_task中,成为一个异步任务
执行任务:任务可以通过operator()或者在新线程中调用std::thread来执行,packaged_task对象必须通过std::move传递,因为packaged_task不允许复制
调用std::future的get()方法,调用线程可以等待异步任务完成并获取其返回值,如果任务尚未完成,get()将阻塞直到结果可用

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】—— Java面向对象进阶:继承小练习-Java中实现圆柱体类及其体积计算

目录 1. 定义圆类&#xff08;Circle&#xff09; 2. 定义圆柱体类&#xff08;Cylinder&#xff09; 3. 测试圆柱体类 4. 总结 在Java中&#xff0c;我们可以通过面向对象的方式来模拟现实世界中的物体&#xff0c;比如圆柱体。本篇文章将通过一个简单的示例来展示如何定义…

全国大学生数学建模竞赛系统使用手册

注意&#xff01;国赛是学校统一报名&#xff0c;所以如果在操作上有任何不清楚的地方&#xff0c;一定要在赛前即使询问自己学校组织数模的老师&#xff01;并详细阅读本文和官网通知&#xff0c;以及&#xff1a;数模国赛提交MD5码和论文的坑&#xff01; 数模比赛的建模手、…

【Python报错已解决】“ModuleNotFoundError: No module named ‘timm‘”

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言&#xff1a;一、问题描述1.1 报错示例&#xff1a;当我们尝试导入timm库时&#xff0c;可能会看到以下错误信息。…

颠覆传统:基于全文索引驱动下的高效一对多表结构设计!

首发公众号&#xff1a;赵侠客 引言 在数据库表结构设计中&#xff0c;一对多&#xff08;1:N&#xff09;关系的处理是非常常见需求&#xff0c;如一个用户有多个分类或角色。传统关系型数据库表设计方式通常要包括三张表&#xff1a;用户表、分类表、以及用户与分类之间的关…

LC开源电路的学习(一)

TI的升压芯片&#xff0c;电压虽然能升高&#xff0c;但是带来的问题就是最大电流大幅降低&#xff1a; CC1和CC2芯片接快充芯片之后&#xff0c;直接接到单片机的下载口&#xff1a; 这个有点意思&#xff0c;用导线换电阻&#xff1a; 、 PD快充芯片CH224K需要连接typeC的D…

华为云征文|基于Flexus云服务器X实例的应用场景-部署脚手架开源项目若依

&#x1f534;大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 先看这里 写在前面**Flexus X实例**的云服务器简介环境准备若依项目拉取导入数据库启动本地项目&#xff08;后端&#xff09;启动本地项目&#xff08;前端&#xff09;打包后…

图片转为PDF怎么弄?看这里,三款软件助你一键转换!

嘿&#xff0c;朋友们&#xff01;现在信息这么多&#xff0c;图片在我们学习、工作、生活中帮了大忙。但有时候&#xff0c;我们想把图片整理好、分享给别人或者打印出来&#xff0c;PDF格式就特别合适。PDF文件不管在哪儿打开&#xff0c;内容都不会变样&#xff0c;还能加密…

Pandas 9-绘制柱状图

1. 准备数据 首先&#xff0c;需要准备一个DataFrame。 import pandas as pd # 创建一个DataFrame data { Name: [Alice, Bob, Charlie, David], Age: [24, 27, 22, 32], City: [New York, Los Angeles, Chicago, Houston], Score: [85, 92, 78, 88]} df pd.…

【生成模型系列(初级)】自编码器——深度学习的数据压缩与重构

【通俗理解】自编码器——深度学习的数据压缩与重构 第一节&#xff1a;自编码器的类比与核心概念 1.1 自编码器的类比 你可以把自编码器想象成一个“智能压缩机”&#xff0c;它能够把输入的数据&#xff08;比如图片&#xff09;压缩成一个更小的表示&#xff08;编码&#…

超声波模块

HCSR04超声波模块是一种常用的测距模块&#xff0c;它通过检测超声波发射后遇到障碍物所反射的回波&#xff0c;从而测量出与障碍物之间的距离。以下是对HCSR04超声波模块的详细讲解&#xff1a; 一、模块组成与工作原理 组成&#xff1a;HCSR04超声波模块主要由两个压电陶瓷超…

【我的Android进阶之旅】快来给你的Kotlin代码添加Markdown格式的注释吧!

文章目录 一、 传统 HTML 格式注释二、 Markdown 格式注释三.、Markdown格式注释详解3.1. 基础语法3.1.1 单行注释3.1.1 多行注释3.2 标题3.3 列表3.4 加粗和斜体3.5 代码块3.6 链接3.7 引用3.8 表格3.9. 图片3.10. 示例代码3.11. 注释模板的使用场景3.12 实例示例四、总结在 A…

2024年9月深圳200万~300万的三房笔记

​整理了2024年9月深圳200万~300万的三房笔记&#xff0c;数据可能有​出入。有些商品房数据是我看到工抵房的数据&#xff0c;群里说工抵房的房价数据需要乘以1.2就比较接近当前现场的价格​。对于我个人来说关注地铁&#xff0c;即是否方便打工还有价格​。看着一些商品房的工…

【华三】不懂链路聚合?看这篇就够了!华三配置详解

【华三】不懂链路聚合&#xff1f;看这篇就够了&#xff01;华三配置详解 背景链路聚合基本概念聚合组和聚合接口的类型二层聚合组/二层聚合接口三层聚合组/三层聚合接口聚合接口特性 聚合接口参考端口成员端口 操作Key成员端口的配置分类协议类配置-第一类配置属性配置-第二类…

Day 1 : 数据结构

引入 以张三为例&#xff1a;CEF不能同时举办。 数据的逻辑结构 数据结构是什么 研究计算机数据之间的关系 逻辑结构和存储结构及其操作 基本概念 数据 数据元素 逻辑结构 按前趋和后继数将逻辑结构分为&#xff1a;线性结构和非线性结构。 即&#xff1a;找前…

云首席产品规划专家的必修课

大家好&#xff0c;我是卢旗。 今天和大家探讨一下云计算规划专家的必备研究内容。 一、市场与客户需求分析&#xff1a; 1&#xff0c;市场调研&#xff1a;深入了解当前及未来云计算市场的趋势、竞争格局、客户需求变化等&#xff0c;识别出潜在的市场机会和威胁。 结合20…

C++ string类—容量、元素获取

一、Capacity size&#xff1a;string类对象中字符的个数为size&#xff1b;length&#xff1a;size作用一样&#xff0c;返回string对象中有效数据个数&#xff1b;capacity:一个string对象的容量capacity决定了这个对象能存储多少字符&#xff08;不包括\0&#xff09;&…

活动系统开发之采用设计模式与非设计模式的区别-需求整理

用户需求(活动系统)&#xff1a; 1、活动类型&#xff1a;答题、图片展示、签到、抽奖、组团等活动 2、活动介绍&#xff1a; a、答题活动&#xff1a; 第一种是签到后&#xff0c;随机抽取10道题&#xff0c;答对8到就可以抽奖&#xff1b; 第二种是随机抽取一道题&#xff0…

Python优化算法24——基于觅食生境选择的粒子群算法(FHSPSO)

科研里面优化算法都用的多&#xff0c;尤其是各种动物园里面的智能仿生优化算法&#xff0c;但是目前都是MATLAB的代码多&#xff0c;python几乎没有什么包&#xff0c;这次把优化算法系列的代码都从底层手写开始。 需要看以前的优化算法文章可以参考&#xff1a;Python优化算…

c/c++基础及类和对象汇总

目录 c基础 extern关键字及c中&#xff08;隐式类型转换时&#xff09;的引用 c中的引用&#xff08;&&#xff09;及&做返回值问题 c语言中的宏函数及c的内联函数及auto及NULL 计算类的大小及深入理解this指针&#xff08;深入浅出&#xff09; c中的const权限及s…

C语言典型例题58

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 例题4.10 求100~200中的全部素数。 代码&#xff1a; //《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 //例题4.10 求100~200中的全部素数。#include <stdio.h> #include <math.h>int m…