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

2308C++简单异步懒

Lazy

LazyC++20无栈协程实现.一个Lazy闭包一个懒求值的计算任务.

使用Lazy

想用Lazy,需要先#inlude<async_simple/coro/Lazy.h>,再实现返回类型为Lazy<T>的协程函数即可.如:

# 包含<简单异步/协程/.h><>任务1(整 x){协中 x;//带有`协中`的函数是协程函数.
}

Lazy中也可协待其他可等待对象:

# 包含<简单异步/协程/.h><>任务2(整 x){协待 标::总是挂起{};协中 x;
}

启动方式

一个Lazy应该以协待,同步等待.start(回调)方式启动.

协待启动

如:

# 包含<简单异步/协程/.h><>任务1(整 x){协中 x;
}<>任务2(){动 t=任务1(10);动 x=协待 t;//开始执行t协程断定(x==10);
}

协待Lazy时会触发对称变换
,它会挂起当前协程并立即执行协待Lazy.执行完协待Lazy后,会使用对称变换来唤醒当前挂起的协程.
并按协待式的值返回Lazy<T>中所包含的值.

需要注意,协待一个Lazy时并不能假设一定会执行协待后的语句.原因如:
1,未完成等待的任务.
2,分发器实现有bug,最后不一定会执行了提交到分发器的任务.
3,执行等待任务过程中出现了异常,此时协待会直接返回该异常到当前正在等待的Lazy,而不会执行之后的语句了.

同时需要注意,使用协待启动Lazy需要当前函数也为C++20无栈协程.

.start(回调)启动

如:

# 包含<简单异步/协程/.h>
# 包含<io流><>任务1(整 x){协中 x;
}<>任务2(){动 t=任务1(10);动 x=协待 t;断定(x==10);
}
空 函数(){任务2().开始([](<>结果){(结果.有错误())::输出<<"任务2错误.\n";异标::输出<<"任务2成功.\n";});
}

Lazy<T>::start(回调)中的回调需要是一个接受Try<T>类型参数的callable对象.

调用Lazy<T>::start(回调)方法后,会立即开始执行Lazy,并在Lazy执行完成后,把Lazy的结果传入回调中执行.
在设计上,start非阻塞异步调用接口.语义上,用户可认为调用start后立即返回.用户不应假设调用start后会何时返回.这是由Lazy的执行情况决定的.

对不需要回调的情况,用户可写:

任务().开始([](&&){});

同步等待启动

如:

# 包含<简单异步/协程/.h><>任务1(整 x){协中 x;
}<>任务2(){动 t=任务1(10);动 x=协待 t;断定(x==10);
}
空 函数(){动 值=同步等待(任务2());//同步等待,执行完任务2
}

在启动Lazy的同时,同步等待阻塞当前进程直到执行完同步等待Lazy.同步等待属于同步阻塞.

取值与异常处理

Lazy<T>类型的任务对象,协待任务的返回类型为T.如果执行任务过程中有异常,则协待任务会直接抛该异常.

如:

<>(){抛 标::运行时错误("测试");协中 1;
}<>(){整 资源;{资源=协待 福();}(...){::输出<<"福有错.置结果为-1.\n";资源=-1;}协中 资源;
}
空 栏(){动 资源=同步等待(());::输出<<"结果:"<<资源<<"\n";//资源 的值会是-1.
}

需要注意,虽然协待任务时有可能会抛异常,但总是使用try...catch包装协待并不是推荐的做法.一方面这样写确实很麻烦,另一方面,当协待抛异常时,协程的框架保证了会由协待所在的协程处理抛的异常.

如:

<>(){抛 标::运行时错误("测试");协中1;
}<>(){整 资源;资源=协待 福();断定();//不会执行,因为上一行会抛异常.协中 资源;
}<>(){协中 协待 条();
}
空 正常(){{同步等待(());}(...){//可在此抓到异常.}
}
空 正常2(){().开始([](<>结果){(结果.有错误())::输出<<"栏有错误!!\n";});
}

当由协待组成的任务链的某一层出现异常时,异常会一层层地往上抛.对同步等待形式的启动方式,可在同步等待处加上try..catch语句.而对实际中更常用的.start方式,可在回调处通过Try对象取是否出现异常.

如果不想让异常直接往上抛,而想直接处理,则可用coAwaitTry接口.如:

<>(){抛 标::运行时错误("测试");协中 1;
}<>(){<>资源=协待 福().试协待();(资源.有错误()){::异常针 错误=资源.取异常();//计算错误}协中 资源.();
}

Lazy<T>类型的对象任务,协待任务.coAwaitTry()的返回值类型为Try<T>.

调度懒

调度懒在语义上是绑定了ExecutorLazy.调度懒协待 Lazy时并不会使用对称变换立即执行Lazy,而是唤醒Lazy的任务,并提交它到调度懒绑定的Executor中.因为语义上调度懒也是Lazy,所以调度懒也能使用Lazy协待,.start同步等待接口.

创建调度懒

不能直接创建调度懒,也不能像Lazy一样作为协程的返回类型.只能通过Lazyvia接口创建调度懒,如:

空 福(){执行器::简单执行器 e1(1);动 加一=[&](整 x)-><>{动 临=协待 取值(x);协中 临+2;};再安排懒 分发=加一().通过(&e1);同步等待(分发);//由分发器决定何时开始`加一`的执行
}

分发器的传递

在编写计算任务时,都只使用Lazy.当想要为一个计算任务指定分发器时,只需要在任务开始阶段指定分发器即可.
指定的分发器会随着协待一路传递下去.
如:

# 包含<简单异步/协程/.h>
# 包含<io流><>任务1(整 x){协中 协待 计算(x);
}<>任务2(整 x){协中 协待 任务1(x);
}<>任务3(整 x){协中 协待 任务2(x);
}<>任务4(整 x){协中 协待 任务3(x);
}
空 函数(整 x,执行器*e){任务4(x).通过(e).开始([](&&结果){::输出<<"完成计算x的任务.\n结果是"<<结果<<"\n";});
}

在上例中,任务1...任务4转发计算任务的调用链,其结果都是以Lazy表示的.
func中,在创建了任务4Lazy后,为其指定了分发器e得到了一个调度懒.
之后调用.start时,不仅任务4具体何时执行是由分发器决定的.
包括任务3,任务2,任务1何时执行,也都是由分发器决定的.

总之,当需要为多个Lazy组成的任务链指定分发器时,只需要在任务链的开头指定分发器就好了.

Collect

collectAll

当有多个计算任务时,一个很常见需求是等待所有计算任务完成以取所有任务的结果后再进一步的计算.
可用collectAll接口完成该需求.如:

<>(){::向量<<>>输入;输入.压后(计算任务(1));输入.压后(计算任务(2));向量<<>>=协待 收集所有(::移动(输入));协中 出[0].()+[1].();
}

collectAll表示开始执行参数中所有Lazy的任务.collectAll是一个协程,要用协待以取结果.

参数要求

collectAll接受两类的参数:
1,参数类型:std::vector<Lazy<T>>.返回类型:std::vector<Try<T>>.
2,参数类型:Lazy<T1>,Lazy<T2>,Lazy<T3>,....返回类型:std::tuple<Try<T1>,Try<T2>,Try<T3>,...>.

第二个参数类型的示例为:

<>计算整();<双精>计算双精();<::>计算串();<>(){::元组<<>,<双精>,<::>>资源=协待 收集所有(计算整(),计算双精(),计算串());<>整资源=::<0>(资源);(整资源.有错误())::输出<<"计算整()时,错误\n";异标::输出<<"计算整结果为:"<<整资源.()<<"\n";//...
}

其他接口

collectAllPara

如果colletAll的所有参数都是Lazy而非调度懒,则collectAll会单线程地执行每个Lazy.
有两个办法:
1,为所以参数绑定Lazy使其成为调度懒.
2,使用collectAllPara.

使用collectAllPara需要注意其所在协程必须要绑定分发器,否则依然是单线程执行所有Lazy.

如:

<>(){::向量<<>>输入;输入.压后(计算任务(1));输入.压后(计算任务(2));向量<<>>=协待 收集所有段(::移动(输入));协中 出[0].()+[1].();
}
空 条(){//动 t=同步等待(福());//错误!福()没有绑定分发器!依然会串行执行.执行器::简单执行器 e1(1);动 t=同步等待(().通过(&e1));//正确,提前为 福()绑定分发器
}

collectAllPara的参数与返回类型和collectAll相同.

collectAllWindowed

当需要分批次的执行并发任务时,可用collectAllWindowed.
collectAllWindowed的参数列表及语义为为:
1,size_t maxConcurrency.每个批次所规定的任务数.
2,bool yield.在执行完当前批次后,是否需要yield使当前协程退出,把控制权交给其他协程.
3,std::vector<Lazy<T>>lazys.所有需要执行的任务.

如:

<>(::向量<<>>输入);<>批量求和(大小型 总数,大小型 批大小){::向量<<>>输入;(动 i=0;i<总数;i++)输入.压后(计算任务());动 出=协待 收集所有窗口(批大小,,::移动(输入));协中 协待 和(::移动());
}

collectAny

只需要等待所有计算任务中的任意一个任务完成时,可用collectAny来取第一个完成的任务结果.此时会忽略其他尚未完成任务的结果.
collectAny接受的参数为std::vector<Lazy<T>>.返回类型为Lazy<CollectAnyResult<T>>.

CollectAnyResult的数据结构为:

<型名 T>
构 收集任一结果<>{大小型 _索引;<T> _值;
};

其中_idx表示第一个完成的任务的编号,_value表示第一个完成的任务的值.

如:

<>(){::向量<<>>输入;输入.压后(计算任务(1));输入.压后(计算任务(2));动 结果=协待 收集任一(::移动(输入));::输出<<"第1任务索引为"<<结果._索引<<"\n";(结果._值.有错误())::输出<<"失败了.\n";异标::输出<<"结果:"<<结果._值.()<<"\n";
}

相关文章:

2308C++简单异步懒

Lazy Lazy由C20无栈协程实现.一个Lazy闭包一个懒求值的计算任务. 使用Lazy 想用Lazy,需要先#inlude<async_simple/coro/Lazy.h>,再实现返回类型为Lazy<T>的协程函数即可.如: # 包含<简单异步/协程/懒.h>懒<整>任务1(整 x){协中 x;//带有协中的函数…...

Linux常规操作命令

日升时奋斗&#xff0c;日落时自省 目录 1、vim 1.1、工作模式 1.2、末行模式操作相关命令 1.2.1、保存退出操作 1.2.2、查找替换 1.3、输入模式操作相关命令 1.3.1、移动相关命令 1.3.2、删除和剪切命令 1.3.3、复制操作 1.3.4、撤销 2、head 3、tail 4、ps 5、…...

日期切换

组件&#xff1a;<template><div class"time-picker"><el-radio-group size"small" v-model"timeType" change"changePickerType"><el-radio-button label"hour" v-if"isShow">时</el…...

怎么裁剪视频大小尺寸?简单的裁剪方法分享

怎么裁剪视频的画面大小尺寸呢&#xff1f;有时当我们下载下来一段视频&#xff0c;由于视频的画面大小比例不同&#xff0c;会有很多的黑边&#xff0c;我们不管是观看还是进行二次编辑都非常影响体验&#xff0c;而调整视频画面比例以适应观众的设备或平台&#xff0c;比如将…...

智慧工地源码,Spring Cloud+ Vue+UniApp开发,微服务架构

智慧工地源码&#xff0c;智慧工地云平台源码 智慧工地APP源码 智慧工地的核心是数字化&#xff0c;它通过传感器、监控设备、智能终端等技术手段&#xff0c;实现对工地各个环节的实时数据采集和传输&#xff0c;如环境温度、湿度、噪音等数据信息&#xff0c;将数据汇集到云…...

【Hystrix技术指南】(5)Command创建和执行实现

创建流程 构建HystrixCommand或者HystrixObservableCommand对象 *使用Hystrix的第一步是创建一个HystrixCommand或者HystrixObservableCommand对象来表示你需要发给依赖服务的请求。 若只期望依赖服务每次返回单一的回应&#xff0c;按如下方式构造一个HystrixCommand即可&a…...

学习笔记-JAVAJVM-JVM的基本结构及概念

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 什么是JVM 原文连接&#xff1a; 原文连接 JVM是J…...

ubuntu20.04 docker 下编译 tensorflow-gpu

ubuntu20.04 安装tensorflow-gpu 配置&#xff1a; 系统 ubuntu 20.04 LTS 显卡 GTX 1060 6G 1 安装cudatoolkit &#xff08;我选 CUDA Toolkit 12.2 &#xff09; NVIDIA CUDA Installation Guide for Linux https://docs.nvidia.com/cuda/cuda-installation-guide-linux/in…...

❤ VUE3 项目路由拦截器配置(二)

❤ VUE3 项目 路由拦截器进一步 配置 路由拦截抽离为单个模块permission.ts 路由配置规则 白名单&#xff08;直接进入&#xff09; PC页面和PC子页面&#xff08;直接进入&#xff09; 后台页面&#xff08;验证token &#xff09; 没有token> 后台登录页面 有token> 后…...

Filament 如何自定义登录页面

官方的页面太简约了&#xff0c;而且可供修改的范围太少了 通过发布官方资源可以看到 resources/views/vendor/filament-panels/pages/auth/login.blade.php <x-filament-panels::page.simple>if (filament()->hasRegistration())<x-slot name"subheading&…...

百度智能云“千帆大模型平台”最新升级:接入Llama 2等33个模型!

今年3月&#xff0c;百度智能云推出“千帆大模型平台”。作为全球首个一站式的企业级大模型平台&#xff0c;千帆不但提供包括文心一言在内的大模型服务及第三方大模型服务&#xff0c;还提供大模型开发和应用的整套工具链&#xff0c;能够帮助企业解决大模型开发和应用过程中的…...

[保研/考研机试] KY129 简单计算器 浙江大学复试上机题 C++实现

描述 读入一个只包含 , -, *, / 的非负整数计算表达式&#xff0c;计算该表达式的值。 输入描述&#xff1a; 测试输入包含若干测试用例&#xff0c;每个测试用例占一行&#xff0c;每行不超过200个字符&#xff0c;整数和运算符之间用一个空格分隔。没有非法表达式。当一行中…...

推出 Elasticsearch 查询语言 (ES|QL)

作者&#xff1a;Costin Leau 我很高兴地宣布&#xff0c;经过大约一年的开发&#xff0c;Elasticsearch 查询语言 (ES|QL) 已准备好与世界共享&#xff0c;并已登陆 Elasticsearch 存储库。 ES|QL 是 Elasticsearch 原生的强大声明性语言&#xff0c;专为可组合性、表现力和速…...

机器学习 day32(神经网络如何解决高方差和高偏差)

解决高偏差和高方差的新方法 之前&#xff0c;我们需要通过选取多项式次数以及正则化参数λ&#xff0c;来平衡高方差和高偏差 只要训练集不是特别大&#xff0c;那么一个大型的神经网络总能很好的适应训练集&#xff0c;即它的Jtrain很低由此可以得出&#xff0c;若要减小Jt…...

Web前端之NodeJS、Vue

文章目录 一、Babel转码器1.1 Babel安装流程1.2 Babel命令行转码 二、Promise对象三、测试方式四、Vue&#xff08;渐进式JS框架&#xff09;4.1 准备4.2 创建一个项目4.3 运行一个项目 五、模板语法5.1 文本5.2 原始html5.3 属性Attribute5.4 使用JavaScript表达式 六、条件渲…...

冠达管理:银行定增是利好还是利空?

银行定增是指银行经过向特定投资者定向发行股票的方法进行增发。这种方法被认为可认为银行提供本钱充足、拓展融资渠道、增强抵挡危险的才能。但是&#xff0c;关于银行定增是否对商场和投资者带来积极影响的讨论一向存在。本文将从多个角度进行剖析&#xff0c;以讨论银行定增…...

背上小书包准备run之TypeScript篇

这TypeScript我真不知道面试会咋问。。。 哦以前还写过一篇基础⬇️ Typescript 基础易理解-------冲冲冲_ts和js有什么区别_慢谷的博客-CSDN博客 typescript是啥&#xff1f;与javascript的区别&#xff1f; TypeScript是一个强类型的JavaScript超集&#xff0c;可编译为纯…...

什么是绩效管理?绩效管理包括哪些内容?

阅读本文您可以了解&#xff1a;1、绩效管理的定义&#xff1b;2、绩效管理的内容&#xff1b; 一、什么是绩效管理 绩效管理是一种组织和管理方法&#xff0c;旨在确保员工的工作与组织的目标保持一致&#xff0c;以及激励和提高员工的工作表现。它涉及设定明确的目标和标准&…...

Java基础练习八(二维数组)

1.装水问题 有一个 异形 容器&#xff0c;用一个 n * n 的二维数组来表示。其中 1 表示容器实心部分&#xff0c; 0 表示空心部分。现使用此容器装水&#xff0c;能装多少水&#xff08;每个元素都表示一份水&#xff0c;只有有挡板的部分能装水&#xff09;&#xff1f; publi…...

Biopython序列比对

从InterPro网站&#xff08;https://www.ebi.ac.uk/interpro/download/Pfam/&#xff09;下载多序列比对文件Pfam-A.seed.gz&#xff08;含多个多序列比对&#xff09; ​wget https://ftp.ebi.ac.uk/pub/databases/Pfam/current_release/Pfam-A.seed.gz解压&#xff0c;取第一…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...