async++库的使用示例
1、普通异步函数
如前面的博客介绍的,这个库中提供了async::spawn方法,这个方法通常用来启动异步函数,这个框架会利用线程池去完成函数,因此要注意数据安全。正因为将任务放到了单独的线程执行,并且还有调度开销,因此简单的任务最好不要使用这种方法,得不偿失。示例代码如下:
void demo_async1() {std::mutex mutex;auto task1 = async::spawn([&mutex]{{std::lock_guard<std::mutex> lock(mutex); std::cout << "this is in async thread" << std::endl;}return "hello world!!!"; }); while(!task1.ready()) {std::lock_guard<std::mutex> lock(mutex);std::cout << "this is in main thread" << std::endl;}task1.wait();// 这里会获取任务的返回值,即"hello world!!!"auto ret = task1.get();std::cout << ret << std::endl;
};
2、带有子任务的普通异步函数
async::spawn函数返回的仍然是一个任务,因此可以连续使用then来执行子任务,示例代码如下:
void demo_async2() {async::spawn([] {return "hello world";}).then([](const std::string& s) {return s;}).then([](async::task<std::string> task) {std::cout << task.get() << std::endl;});
}
有没有发现第一个子任务所执行的函数参数是std::string,而第二个子任务所执行的函数参数是async::taskstd::string task,而前面两个任务返回的都是字符串。这是因为异步编程中的 .then() 方法和 async::task 类型的处理方式有些特殊。在链式调用中,.then() 并不仅仅是一个普通的函数调用,它是用来接收一个异步任务完成后的结果,并且会返回一个新的异步任务。这意味着第一个子任务返回的并不是字符串,返回的字符串会被封装成async::taskstd::string,所以第二个子函数的参数类型必须是 async::taskstd::string。而主任务的返回值是std::string,所以第一个子任务的函数参数可以是std::string。
3、when_any和when_all的使用
when_any是任务集合中有一个任务完成就会返回,when_all是多有的任务完成才会返回。需要注意的是,when_any并不是第一个任务完成了就不执行其他的任务,其它的任务仍在执行,只不过when_any不会等他们执行完再返回。这里在测试的时候,如果测试when_all,一定要先注释when_any,否则程序会崩溃,原因就是task和shared_task的原因。它们返回的包含结果的数据结构都是std::tuple类型的,想取得结果要么使用辅助函数,要么使用std::get<0>(results).get()这种。不能使用for遍历,因为tuple的各元素大小可能不一样。也不可以使用std::get<first_result.index>,原因很简单,模版函数需要再编译时确定值,而不可以在运行时确定。
void demo_async3() {// 定义三个异步任务,分别模拟不同的执行时间auto task1 = async::spawn([] {std::this_thread::sleep_for(std::chrono::seconds(3)); // 模拟耗时任务std::cout << "Task 1 completed!" << std::endl;return 1;});auto task2 = async::spawn([] {std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时任务std::cout << "Task 2 completed!" << std::endl;return 2;});auto task3 = async::spawn([] {std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时任务std::cout << "Task 3 completed!" << std::endl;return 3;});// // 使用 when_any 等待最早完成的任务// auto any_result = async::when_any(task1, task2, task3);// any_result.wait(); // 等待第一个任务完成// auto first_result = any_result.get();// std::cout << "First completed task returned: " << first_result.index << std::endl;// 使用 when_all 等待所有任务完成auto all_result = async::when_all(task1, task2, task3);all_result.wait(); // 等待所有任务完成auto results = all_result.get();// 因为是Tuple,静态容器,每个元素的大小可能不一样,所以可以用这种方式访问// 如果是C++1,可以使用std::apply()来遍历tuplestd::cout << std::get<0>(results).get() << std::endl;std::cout << std::get<1>(results).get() << std::endl;std::cout << std::get<2>(results).get() << std::endl;
}
4、async::cancellation_token的使用
该异步框架提供了一个async::cancellation_token,它主要用来控制子任务的执行进度,是不是在主线程中取消子任务的执行,这样可以使得子线程中通过其控制子线程内部的执行进度,是不是取消(当然也可以做一些逻辑的控制)
void demo_async4() {async::cancellation_token c;auto t = async::spawn([&c] { std::cout << "-----line 68" << std::endl;async::interruption_point(c);while(!c.is_canceled());std::cout << "-----line 70" << std::endl;});sleep(1);std::cout << "-----line 79" << std::endl;c.cancel(); t.get();std::cout << "-----line 82" << std::endl;
}
5、事件任务的使用
我认为时间任务的主要作用是在主线程中控制子任务的执行时间点,并可以像子任务重设置参数。
void demo_async5() {async::event_task<int> e;auto t = e.get_task();// 这里只是将后面的任务放到了e的continuation_vectort.then([](int result) { std::cout << result << std::endl; });// 执行主任务,并将参数传给子任务,触发子任务e.set(42);
}
6、共享任务的使用
共享任务的优点是可以多次获取任务的结果,不像普通的任务那样,获取完结果,就会把内存释放掉。缺点是使用了引用计数,增加了资源消耗,但是现代计算机中,这些资源的消耗造成的影响较小,这里的代码必须加share(),根因和task类shared_task类的定义有关系,task类不允许拷贝,但是允许移动构造,但是shared_task都是可以的,模仿的std::future和std::shared_future的关系。
// 从测试代码中可以看出,我们可以利用共享任务,将其以参数的形式传到其它任务中
void demo_async6() {// 使用 async::spawn 创建异步任务并使用 .share() 方法共享auto t = async::spawn([] {std::cout << "Parent task" << std::endl;return 42; // 返回一些结果}).share();// 创建两个任务,它们共享 tauto task1 = async::spawn([t] {auto result = t.get(); // 获取共享任务的结果std::cout << "Task 1 result: " << result << std::endl;});auto task2 = async::spawn([t] {auto result = t.get(); // 获取共享任务的结果std::cout << "Task 2 result: " << result << std::endl;});// 等待任务完成task1.get();task2.get();
7、测试程序
直接贴代码
#include <iostream>
#include <mutex>
#include <ctime>
#include <unistd.h>
#include "../include/async++.h"
/*
上面的示例
*/
int main() {// demo_async1();// demo_async2();demo_async3();// demo_async4();//
相关文章:
async++库的使用示例
1、普通异步函数 如前面的博客介绍的,这个库中提供了async::spawn方法,这个方法通常用来启动异步函数,这个框架会利用线程池去完成函数,因此要注意数据安全。正因为将任务放到了单独的线程执行,并且还有调度开销&…...
springboot基于微信小程序的手机银行系统
Spring Boot基于微信小程序的手机银行系统是一种结合现代Web技术和移动应用优势的创新金融服务平台。 一、系统背景与意义 随着信息技术的快速发展和用户对便捷金融服务需求的日益增长,传统手机银行系统的人工管理方法已逐渐显露出效率低下、安全性低以及信息传输…...
25/1/22 算法笔记<ROS2> TF变换
TF(Transform) 是 ROS(Robot Operating System)中的一个核心功能,用于管理和发布坐标系之间的变换关系。TF 的主要作用是描述机器人系统中各个部分(如传感器、执行器、底盘等)之间的位置和姿态关…...
Android系统开发(六):从Linux到Android:模块化开发,GKI内核的硬核科普
引言: 今天我们聊聊Android生态中最“硬核”的话题:通用内核镜像(GKI)与内核模块接口(KMI)。这是内核碎片化终结者的秘密武器,解决了内核和供应商模块之间无尽的兼容性问题。为什么重要&#x…...
dp 凸优化
时间有点仓促,过几天会补。 来自 czz 学长的课,SMWC -> Day4 。 目录 凸函数介绍WQS二分1. P2619【国家集训队 2】Tree I2. CF739E Gosha is hunting 闵可夫斯基和1. QOJ-5421 Factories Once More2. GD 省集 tower Slope Trick1. CF713C2. ABC217H3.…...
详细介绍:Kubernetes(K8s)的技术架构(核心概念、调度和资源管理、安全性、持续集成与持续部署、网络和服务发现)
目录 前言1、K8s架构概述1.1、控制面(Control Plane)1.2、工作节点(Worker Node) 2、Kubernetes核心概念2.1、Pod2.2、ReplicaSet2.3、Deployment2.4、Service2.5、Namespace2.6、ConfigMap与Secret2.7、Persistent Volume&#x…...
[SAP ABAP] Dialog屏幕开发
Dialog屏幕开发在SAP ABAP环境中被广泛应用于创建交互式的用户界面,允许终端用户与应用程序进行互动 Dialog屏幕开发相关资料 [Dialog屏幕开发] 设置GUI Status 菜单/GUI Title 标题 [Dialog屏幕开发] 屏幕绘制(文本/输入框/按钮控件)...
安全测试之 SSTI 模板注入入门
文章目录 一、什么是SSTI?二、python 中的 Jinja2 漏洞验证三、Java 的 Thymeleaf 模版漏洞验证四、小结 一、什么是SSTI? SSTI(Server-Side Template Injection)是一种服务器端模板注入漏洞,它出现在使用模板引擎的W…...
滑动窗口解题模板
滑动窗口适用于固定长度的窗口问题,或者需要动态维护一个窗口的场景。 模板 public int slidingWindowTemplate(int[] nums, int k) { int n nums.length; int maxSum 0; // 记录最大值(或最小值) int windowSum 0; // 当前窗口的值 …...
SOC和SOH的含义
SOC 和 SOH 是在电池管理系统中常见的两个概念,通常用于描述电池的状态,以下是具体解释: SOC(State of Charge) 定义:荷电状态,也叫剩余电量,反映的是电池在一定条件下当前所剩余的…...
Genetic Prompt Search via Exploiting Language Model Probabilities
题目 利用语言模型概率的遗传提示搜索 论文地址:https://www.ijcai.org/proceedings/2023/0588.pdf 项目地址:https://github.com/zjjhit/gap3 摘要 针对大规模预训练语言模型(PLMs)的即时调优已经显示出显著的潜力,尤其是在诸如fewshot学习…...
1561. 你可以获得的最大硬币数目
class Solution:def maxCoins(self, piles: List[int]) -> int:piles.sort()res,n0,len(piles)for i in range(n//3):respiles[n-2-2*i]return res这里如果"你"想要获取最大,那么从最大的开始找 每隔俩算一个最大累计,Bob默认自己从最小那找…...
DNA结合之Motif_1:CNN
1,首先可以识别在KO前后的motif——》由CNN模型做出识别,看看这个有没有什么灵感 2,ZNF143等都可以使用来识别 3,暂时只使用单个peak文件,后期可以使用ENCODE中所有的对应的TF的peak文件 1,文件解压之后…...
kong 网关和spring cloud gateway网关性能测试对比
该测试只是简单在同一台机器设备对spring cloud gateway网关和kong网关进行对比,受限于笔者所拥有的资源,此处仅做简单评测。 一、使用spring boot 的auth-service作为服务提供者 该服务提供了一个/health接口,接口返回"OK"&…...
【2024 CSDN博客之星】个人收获分享
目录 [ C 语言 ] [ 数据结构 ] [ 算法 ] [ C ] [Linux] [Mysql] [Redis 文档学习] [Docker 云原生] [Git] [Qt] 转眼间大学就过了一年半,这一年半间好像习惯了,开心了那就学会吧,不开心了学会吧就开心了......期间在学习上面也走了…...
Codeforces Round 998 (Div. 3)(部分题解)
补题链接 A. Fibonacciness 思路:了解清楚题意,求得是最大的斐波那契的度,数组只有5个数(最多度为3),能列出其对应的式子 或 或 #include <bits/stdc.h> using namespace std; #define int long long void solve() {int …...
[创业之路-261]:《向流程设计要效率》-1-流程体系的建立是一场全方位的变革,一定会遇到各种阻力,需要全方位、系统性地进行流程管理
目录 一、思想和思维方式的转变 1.1 使能流程的战略 1.2 使能流程的组织 1. 流程决定组织 2. 基于流程分配责权利与资源 3. 从“管控”到“赋能” 1.3 使能流程的人才 1. 人才战略:从职能导向到流程导向 2. 能力模型:从职能专家到作战专家 3. …...
深入理解 Spring 的 Lazy Loading:原理、实现与应用场景
延迟加载(Lazy Loading)是 Spring 容器管理 Bean 的一种策略,指 只有在需要时(调用 getBean() 方法获取 Bean 时)才会实例化该 Bean。这是 Spring 提供的一种优化机制,用于提高启动效率和降低资源占用。 1.…...
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
人无完人,持之以恒,方能见真我!!! 共同进步!! 文章目录 一、移除链表元素思路一思路二 二、合并两个有序链表思路:优化: 三、反转链表思路一思路二 四、链表的中间节点思…...
【unity游戏开发之InputSystem——02】InputAction的使用介绍(基于unity6开发介绍)
文章目录 一、InputAction简介1、InputAction是什么?2、示例 二、InputAction参数相关1、点击齿轮1.1 Actions 动作(1)动作类型(Action Type)(2)初始状态检查(Initial State Check&a…...
照着用就行:2026 最新降AIGC软件测评与推荐
2026年真正好用的AI论文降重与改写工具,核心看降重效果、去AI味、格式保留、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 …...
Keil µVision链接器错误204解决方案
1. 问题现象与背景解析最近在使用Keil Vision进行嵌入式开发时,不少工程师遇到了一个令人头疼的链接器错误。具体表现为编译时出现"FATAL ERROR 204: INVALID KEYWORD"的致命错误,错误位置指向链接器控制文件中的特定行。这个问题在C166和C51两…...
基于IRS2092的200W D类功放设计:从PWM原理到保护电路实战
1. 项目概述与核心思路折腾音响功放,从经典的AB类玩到D类,感觉就像是从燃油车换到了电动车,动力响应和效率完全是两个维度。这次要聊的这块“200W Class-D Audio Power Amplifier [150115]”单板功放,就是一个非常典型的D类功放设…...
因果推断与机器学习融合:量化分析社会运动中镇压与抗议的动态关系
1. 项目概述:当数据科学遇见社会运动如果你研究过社会运动,尤其是那些看似突然爆发、席卷全国的抗议浪潮,你可能会被一个核心问题困扰:国家机器的镇压,究竟是浇灭火焰的冷水,还是火上浇油的催化剂ÿ…...
掌握Umi-OCR:5分钟上手开源免费离线文字识别工具
掌握Umi-OCR:5分钟上手开源免费离线文字识别工具 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。…...
基于Arduino与蓝牙模块的六路无线开关控制系统设计与实现
1. 项目概述:用手机蓝牙控制六路LED想不想把手机变成一个无线遥控器,随手一点就能开关家里的灯带、氛围灯,甚至是其他电器?这个项目就是为你准备的。它基于一块功能增强的Arduino兼容板——GlowDuino Uno,配合一个极其…...
纯硬件实现I2C协议:从逻辑门到传感器通信的深度实践
1. 项目概述:用纯硬件“解剖”I2C总线很多朋友在玩传感器,尤其是温湿度传感器时,都绕不开I2C这个通信协议。市面上绝大多数的教程和方案,都会告诉你:找个单片机(比如Arduino、STM32),…...
Sora 2原生MP4输出不兼容Premiere Pro?揭秘H.264/H.265封装层4大隐性缺陷(附MediaInfo诊断模板+自动修复脚本)
更多请点击: https://codechina.net 第一章:Sora 2原生MP4输出不兼容Premiere Pro的根源定位 Sora 2生成的原生MP4文件虽符合ISO/IEC 14496-14规范,但其底层封装结构与Adobe Premiere Pro对时间码、元数据及视频流编码参数的严格校验逻辑存在…...
免费解锁AMD Ryzen隐藏性能:SMUDebugTool终极指南
免费解锁AMD Ryzen隐藏性能:SMUDebugTool终极指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitcod…...
公共卫生机器学习项目中的算法公平性实践:ACAR框架详解
1. 项目概述:当机器学习遇见公共卫生,公平性为何成为“必答题”?在公共卫生领域,机器学习(ML)正以前所未有的速度渗透到疾病监测、风险分层和资源分配等核心环节。想象一下,一个模型被用来预测某…...
