2308C++与有栈比较

原文

避免分配内存

异步操作一般需要存储一些仅在操作中有的跟踪操作进度每操作状态.
如,调用异步Win32I/O函数,要分配并传递OVERLAPPED结构指针.调用者确保完成操作前它有效.
传统基于回调的API,要在上分配此状态,以确保它有适当生命期.多个,则要为每个操作分配和释放它.
如果有性能问题,则可用自定义分配器从池中分配.

但是,使用协程时,可利用挂起协程时,协程帧中的局部变量是活的,从而避免为操作状态分配堆存储.

等待器对象中保存每操作状态,可有效从协程帧中"借用"内存,以便在协待式时存储它.
完成操作后,恢复协程并析构等待器对象,从而释放协程帧中内存.
最终,协程帧仍可能按堆分配.但是,一旦分配,协程帧就可来仅用单个堆分配来完成异步操作.

协程帧当作真正高性能的分配内存器.编译时计算出所有局部变量期望总内存大小,然后可无成本按需分配此内存给局部变量!

示例:实现简单的线程同步原语

异步手动重置事件.
基本要求是,需要多个并发协程是可等待的,且等待时要挂起等待的协程,直到已恢复等待协程,且某个线程调用.set()方法.如果某个线程已调用了.set(),则应该继续而不挂起协程.

最好,还想使它为无异,非堆分配且无锁.示例如下:

T 值;
异步手动重置事件 事件;
//单个调用来生成值
空 生产者()
{= 一些长运行计算();//通过设置事件来发布值.事件.();
}
//支持多个并发用户
任务<> 消费者()
{//在`生产者()`函数中,等待`事件.置()`发出信号.协待 事件;//现在消费"值"是安全的,保证在赋值给"值"后.::输出 <<<<::行尾;
}

先考虑该事件可能的状态:"未置"和"已置".
"未置"状态时,有个等待置它的等待协程列表(可能是空的).
"已置"状态时,不会有等待协程,因为协待此状态事件的协程可继续运行而不会挂起.
该状态可用单个std::atomic<void*>来表示.

1,为"已置"状态保留特殊指针值.本例中,使用事件的this指针,因为知道该指针不可能与列表项地址相同.
2,否则,事件为"未置"状态,且该值是等待协程结构的单链表指针.

在协程帧中的"等待器"对象中存储节点,可避免额外调用堆上的链表分配节点.
因此,从此类接口开始:

类 异步手动重置事件
{:异步手动重置事件(极 初始置 =) 无异;//无需复制/移动异步手动重置事件(常 异步手动重置事件&) =;异步手动重置事件(异步手动重置事件&&) =;异步手动重置事件& 符号=(常 异步手动重置事件&) =;异步手动重置事件& 符号=(异步手动重置事件&&) =;极 是已置() 常 无异;构 等待器;等待器 符号 协待() 常 无异;空 置() 无异;空 重置() 无异;:友 构 等待器;//本为=>已置状态//否则为`=>`未置,`等待器*`链表的头部.可变 标::原子<*> m状态;
};

在此,有个相当直接和简单接口.此时要注意它有个返回未定义等待器的协待()操作符方法.
现在定义等待器.

定义等待器

首先,要知道它在等待哪个异步手动重置事件对象,因此它需要事件引用及构造器来初化它.
还需要充当等待器值链接列表中的节点,因此要有列表中下个等待器对象的指针.

还要存储执行协待式等待协程的协柄,以便事件可在协程变为"已置"时恢复协程.
不必关心协程的承诺类型是什么,所以只使用协柄<>.

最后,要实现等待器接口,因此三个特殊方法:直接协,挂起协恢复协.不想从协待式返回值,恢复协因此可返回.
放在一起,等待器的基本接口如下:

构 异步手动重置事件::等待器
{等待器(常 异步手动重置事件& 事件) 无异: m事件(事件){}极 直接协() 常 无异;极 挂起协(::实验性::协柄<> 等待协程) 无异;空 恢复协() 无异 {}:常 异步手动重置事件& m事件;::实验性::协柄<> m等待协程;等待器* m下个;
};

现在,协待事件时,如果已置事件,不想等待挂起协程.因此,如果已置事件,可定义直接协()返回.

极 异步手动重置事件::等待器::直接协() 常 无异
{中 m事件.是已置();
}

接着,看看挂起协()方法.这一般是大多数可等待类型的神奇的地方.

首先,它需要存储等待协程的协程句柄m等待协程成员中,这样事件稍后可对它调用.恢复()方法.

然后,一旦完成,需要试原子方式把等待器排队到等待链列表中.如果成功加入,则返回true以指示不想立即恢复协程.否则,如果发现事件已并发更改为"已置"状态,则返回以指示应立即恢复协程.

极 异步手动重置事件::等待器::挂起协(::实验性::协柄<> 等待协程) 无异
{//指示是否`"置"`事件状态的特殊`m状态`值.常 空* 常 置状态 = &m事件;//记住等待协程的句柄.m等待协程 = 等待协程;//试原子方式把此`等待者`推到列表头.* 旧值 = m事件.m状态.加载(::获取内存序);{//如果已在"置"状态,请立即恢复.(旧值 == 置状态) 中 假; //更新链表以指向当前头.m下个 = 静转<等待器*>(旧值);//最后,试交换旧的列表头,按新列表头插入该等待器.}(!m事件.m状态.弱比交( 旧值,,::释放内存序,::获取内存序));//已成功入列.保持挂起.中 真;
}

注意,在加载旧状态时使用"获取"内存序,以便如果读取特殊的"set"值时,可查看调用"set()"前的写入.
如果成功比较交换,需要"释放"语义,以便后续调用"set()"时,可看到写入m等待协程和先前写入的协程状态.

填写事件类的其余部分

现在已定义了等待器,再看看异步手动重置事件方法.
首先是构造器.它要按"未置"状态(即nullptr)初化或按"已置"状态(即this)初化空的等待列表.

异步手动重置事件::异步手动重置事件( 极 初始置) 无异
: m状态(初始置?:空针)
{}

接着,is_set()方法非常简单,如果有以下特殊值,则它是"已置":

极 异步手动重置事件::是已置() 常 无异
{中 m状态.加载(::获取内存序) ==;
}

接着是reset()方法.如果为"已置",则改为"未置",否则不变.

空 异步手动重置事件::重置() 无异
{* 旧值 =;m状态.强比交(旧值, 空针,::获取内存序);
}

set()方法,通过用特殊的'已置'this,来交换当前状态来过渡'已置'状态,然后检查旧值.如果有等待协程,则在返回前依次恢复每个协程.

空 异步手动重置事件::() 无异
{//需要"释放",以便后续的`"协待"`可见之前的写入.需要"获取",以便通过`等待协程`来查看先前的写入.* 旧值 = m状态.交换(,::内存序取释放);(旧值 !=){//不是"已置"状态.按已取且需要恢复的等待链接列表头取旧值.* 等待 = 静转<等待器*>(旧值);(等待 != 空针){//在恢复协程之前读`m下个`,因为恢复协程可能会析构等待器对象.* 下个 = 等待->m下个;等待->m等待协程.恢复();等待 = 下个;}}
}

最后,要实现协待()操作符.这只需要构造一个等待器对象.

异步手动重置事件::等待器
异步手动重置事件::符号 协待() 常 无异
{中 等待器{ *};
}

好了.一个可等待的无锁,无分配内存,无异实现的异步手动重置事件.

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

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

相关文章

C语言学习笔记 vscode使用外部console-11

前言 在默认情况下&#xff0c;我们运行C语言程序都是在vscode终端的&#xff0c;在小程序运行时这个是没有问题的&#xff0c;但是当程序变得复杂它就不好用了&#xff0c;这时我们可以将这个终端设置为外部console&#xff0c;这样方便处理更多、更复杂的程序。 步骤 1.点击…

micromamba快速安装(windows版本)

快速安装 Micromamba Micromamba 是一个静态链接的 C++ 可执行文件,在 Windows 上就是一个 micromamba.exe 文件,下载下来就直接可以用,甚至都不需要专门安装。唯一需要做的就是设置 Shell 的 Profile 文件,使 micromamba 成为可以在命令行里调用的一个命令。 Micromamba…

PCB电路板设计基础入门学习笔记

文章目录&#xff1a; 一&#xff1a;Arduino线路板绘制&#xff08;原理图库、PCB库、原理图、PCB图绘制&#xff09; 1.原理图库绘制Schematic Library&#xff08;有现成库&#xff0c;没有就自己画&#xff09;[SCH Library] 方法一&#xff1a;自己依次画 ATMEGA328P-…

HTTP——十一、Web的攻击技术

HTTP 一、针对Web的攻击技术1、HTTP 不具备必要的安全功能2、在客户端即可篡改请求3、针对Web应用的攻击模式 二、因输出值转义不完全引发的安全漏洞1、跨站脚本攻击2、SQL 注入攻击3、OS命令注入攻击4、HTTP首部注入攻击5、邮件首部注入攻击6、目录遍历攻击7、远程文件包含漏洞…

【cluster_block_exception】写操作elasticsearch索引报错

【cluster_block_exception】操作elasticsearch索引b报错 背景导致原因&#xff1a;解决方法&#xff1a; 背景 今天线上elk的数据太多&#xff0c;服务器的空间不足了。所以打算删除一些没用用的数据。我是用下面的request&#xff1a; POST /{index_name}/_delete_by_query…

Promise详细版

promise基础原理到难点分析 常见的Promise的方法解读 扩展async和await深入分析 逐步分析Promise底层逻辑代码 一、Promise基础 1.什么是promise 为了解决回调地狱&#xff1a; //2.设置点击事件btn.onclick function() {//3.创建ajax实例化对象let xhr new XMLHttpRe…

流量,日志分析

wireshark wireshark中有捕获过滤器和显示过滤器 常用的捕获过滤表达式&#xff1a; 常见的显示过滤表达式&#xff1a; 语法&#xff1a; 1.过滤IP&#xff0c;如来源IP或者目标IP等于某个IP 例子: ip.src eq 192.168.1.107 or ip.dst eq 192.168.1.107 或者 ip.addr eq 1…

17 synchronized关键字使用 synchronized方法、synchronized块

synchronized方法、synchronized块 线程的同步不安全的线程示例1&#xff1a;示例2示例3 synchronized方法、synchronized块 线程的同步 并发&#xff1a;同一个对象被多个线程同时操作。 解决方案&#xff1a;让多个线程排队操作对象。 使用队列和锁解决多线程的并发问题。 同…

Harbor.cfg 配置文件参数详解

目录 Harbor.cfg 配置文件参数详解 所需参数&#xff1a; hostname&#xff1a; ui_url_protocol&#xff1a; max_job_workers&#xff1a; db_password&#xff1a; customize_crt&#xff1a; ssl_cert&#xff1a; ssl_cert_key&#xff1a; secretkey_path&#…

力扣:56. 合并区间(Python3)

题目&#xff1a; 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 来源&#xff1a;力扣&#xff08;Lee…

DAY03_Spring—SpringAOPAOP切入点表达式AOP通知类型Spring事务管理

目录 一 AOP1 AOP简介问题导入1.1 AOP简介和作用1.2 AOP中的核心概念 2 AOP入门案例问题导入2.1 AOP入门案例思路分析2.2 AOP入门案例实现【第一步】导入aop相关坐标【第二步】定义dao接口与实现类【第三步】定义通知类&#xff0c;制作通知方法【第四步】定义切入点表达式、配…

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法

文章目录 1 前言2 st.image&#xff1a;嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio&#xff1a;嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video&#xff1a;嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…

MySQL面试1

Mysql的面试突击1 Mysql的体系结构是什么样子的&#xff08;查询语句怎么进行执行的&#xff09; mysql的架构&#xff1a;单进程多线程的架构模式 CLient -----> Server架构 Mysql的链接方式有没有性能优化的点 2个点 查询缓存(Query Cache) MySQL 内部自带了一个缓存模…

spring事务和数据库事务是怎么实现

Spring事务的原理 Spring事务的本质其实就是数据库对事务的支持&#xff0c;没有数据库的事务支持&#xff0c;spring是无法提供事务功能的。对于纯JDBC操作数据库&#xff0c;想要用到事务&#xff0c;可以按照以下步骤进行&#xff1a; 获取连接 Connection con DriverManag…

SpringBoot yml配置注入

yaml语法学习 1、配置文件 SpringBoot使用一个全局的配置文件 &#xff0c; 配置文件名称是固定的 application.properties 语法结构 &#xff1a;keyvalue application.yml 语法结构 &#xff1a;key&#xff1a;空格 value 配置文件的作用&#xff1a;修改SpringBoot自动…

Spring Boot集成EasyExcel实现excel导入导出操作

文章目录 Spring Boot集成EasyExcel实现excel导入导出操作0 简要说明简单使用读操作excel源文件实体类监听器业务代码 写操作*实体类*excel示例业务代码根据参数指定列导出指定哪几列导出复杂头导出 关于数值型&#xff0c;日期型&#xff0c;浮点型数据解决方案实体类接收字符…

算法通过村第二关-链表黄金笔记|K个一组反转

文章目录 前言链表反转|K个一组翻转链表解题方法&#xff1a;头插法处理&#xff1a;穿针引线法处理&#xff1a; 总结 前言 提示&#xff1a;没有人天生就喜欢一种气味而讨厌另一种气味。文明的暗示而已。 链表反转|K个一组翻转链表 给你链表的头节点 head &#xff0c;每 k…

【css】textarea-通过resize:none 禁止拖动设置大小

使用 resize 属性可防止调整 textareas 的大小&#xff08;禁用右下角的“抓取器”&#xff09;&#xff1a; 没有设置resize:none 代码&#xff1a; <!DOCTYPE html> <html> <head> <style> textarea {width: 100%;height: 150px;padding: 12px 20p…

源码分析——HashMap(JDK1.8)源码+底层数据结构分析

文章目录 HashMap 简介底层数据结构分析JDK1.8之前JDK1.8之后 HashMap源码分析构造方法put方法get方法resize方法 HashMap常用方法测试 HashMap 简介 HashMap 主要用来存放键值对&#xff0c;它基于哈希表的Map接口实现&#xff0c;是常用的Java集合之一。 JDK1.8 之前 HashM…

HBase-写流程

写流程顺序正如API编写顺序&#xff0c;首先创建HBase的重量级连接 &#xff08;1&#xff09;读取本地缓存中的Meta表信息&#xff1b;&#xff08;第一次启动客户端为空&#xff09; &#xff08;2&#xff09;向ZK发起读取Meta表所在位置的请求&#xff1b; &#xff08;…