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

协程2 --- 相关概念

文章目录

  • 协程切换方案
  • 协程库的完善程度
  • 协程栈方案
  • 协程调度实现
  • 有栈协程与无栈协程
  • 对称协程与非对称协程

协程切换方案

具体使用和解析看栈切换那个博客

  1. 使用setjumplongjump
    c语言提供的方案
    可参考:libmill

  2. 使用操作系统提供的api:ucontextfiber
    这种方式是最安全可靠的,但是性能比较差。
    可参考:libtask

  3. 自己写汇编码实现
    这种方式的性能可以很好,但是不同系统、甚至不同版本的linux都需要不同的汇编码,兼容性奇差无比。
    可参考:libco

  4. 使用boost
    coroutinecontext等性能很好,boost也帮忙处理了各种平台架构的兼容性问题,不过需要依赖boost框架。
    可参考:libgo

协程库的完善程度

  1. API级
    实现协程上下文切换api,或添加一些便于使用的封装。
    如:boost.context, boost.coroutine

    问题:没有协程调度

  2. 玩具级
    实现了协程调度,无需用户手动处理协程上下文切换。
    如:libmill

    问题:没有HOOK,只实现了一套网络io相关函数,这也意味着涉及网络的第三方库全部不可用了。

  3. 工业级
    以部分正确的方式HOOK了网络io相关的syscall,可以少改甚至不改代码的兼容大多数第三方库。
    如:libco

    问题:没有完整生态,协程间通讯、协程同步、调试等机制不够完善。未能完全模拟syscall的行为,只能兼容行为符合预想的同步模型的第三方库,只能覆盖一部分的第三方库。

  4. 框架级
    以100%行为模拟的方式HOOK了网络io相关的syscall,可以完全不改代码兼容大多数第三方库。
    如:libgo

    问题:由于C++的灵活性,用户行为是不受限的,所以依然存在几个边边角角的难点需要开发者注意:没有gc,TLS的问题,用户不按套路出牌、把逻辑代码run在协程之外,粗粒度的线程锁等等。

  5. 语言级
    语言级的协程实现
    如:golang

    开发者的一切行为都是受限行为,可以实现无死角的完善的协程。
    c++20也支持协程了

协程栈方案

  1. 静态栈
    栈大小固定,有大小难以权衡的问题。
    设置大了,会造成浪费。
    设置小了,会有栈溢出问题。

  2. 分段栈
    GCC支持一种允许栈内存不连续的编译参数,实现原理是在每个函数调用开头都插入一段栈内存检测的代码,如果栈内存不够用了就申请一块新的内存,作为栈内存的延续。
    但是第三方库没有使用这种方式来编译,那就无法在其中检测栈内存是否需要扩展,栈溢出的风险很大。

  3. 拷贝栈
    每次检测到栈内存不够用时,申请一块更大的新内存,将现有的栈内存copy过去,就像std::vector那样扩展内存。
    但C/C++是有指针的,栈内存的copy会导致指向其内存地址的指针失效;又因为其指针的灵活性,修改对应的指针成为了一种几乎不可能实现的事情。

  4. 共享栈(libco)
    申请一块大内存作为共享栈(比如8MB),每次协程挂起时计算协程栈真正使用的内存,copy到私有栈中;唤醒协程时,把协程私有栈的内存copy到共享栈中,这样每次只需保存真正使用到的栈内存量即可。
    这种方案极大程度上避免了内存的浪费,做到了用多少占多少,同等内存条件下,可以启动的协程数量更多,但是协程切换慢,还有引用失效问题。

  5. 虚拟内存栈(libgo)
    申请的内存并不会立即被映射成物理内存,而是仅管理于虚拟内存中,真正对其读写时才会触发缺页中断,分配物理内存;而且基本上是按页递增分配。

协程调度实现

  1. 栈式调度(libco)
    栈式调度是典型的不公平调度。协程队列是一个栈式的结构,每次创建的协程都置于栈顶,并且会立即暂停当前协程并切换至子协程中运行,子协程运行结束(或其他原因导致切换出来)后,继续切换回来执行父协程;越是处于栈底部的协程(越早创建的协程),被调度到的机会就越少。

  2. 星切调度(libgo)
    调度线程 -> 协程A -> 调度线程 -> 协程B -> 调度线程 -> …
    调度线程居中,协程在周围,调度顺序图看起来就像是星星一样,称为星切。
    将当前可调度的协程组织成先进先出的队列(runnable list),顺序pop出来做调度;新创建的协程排入队尾,调度一次后如果状态依然是可调度(runnable)的协程则排入队尾,调度一次后如果状态变为阻塞,那阻塞事件触发后也一样排入队尾,是为公平调度

  3. 环切调度
    调度线程 -> 协程A -> 协程B -> 协程C -> 调度线程 -> …
    调度线程居中,协程在周围,调度顺序图看起来呈环状,称为环切。
    为了突破传统协程库仅用来处理I/O密集型业务的局限,也能适用于CPU密集型业务,可充当并行编程库来使用。

有栈协程与无栈协程

所谓的有栈,无栈并不是说这个协程运行的时候有没有栈。

有栈协程是真的给你开了一个栈(如golang),主流的无栈协程方案(例如C++,Rust等),是把一个协程函数编译成状态机的逻辑,然后用一块临时分配的堆内存去保存这个函数里的变量和协程状态机以及上下文等内容。

无栈不管从效率,内存占用看当然是更优的方案,但是无栈需要编译器支持,有栈只需要编写同一套上下文切换的代码。移植到有栈协程上比无栈也要相对简单,现在主流的无栈协程基本都需要进行侵入式的修改

使用上最大的区别就是协程是否可以在其任意嵌套函数中被挂起,有栈协程是可以的,而无栈协程则不可以。

有栈协程:

  • 每个协程有单独的上下文,可以在任意的嵌套函数中任何地方挂起此协程
  • 不需要编译器做语法支持,通过汇编指令即可实现
  • 需要提前分配一定大小的堆内存保存每个协程上下文,所以会出现内存浪费或者栈溢出
  • 上下文拷贝和切换成本高,性能低于无栈协程

无栈协程:

  • 不需要为每个协程保存单独的上下文,内存占用低
  • 切换成本低,性能更高
  • 需要编译器提供语义支持
  • 只能在这个生成器内挂起此协程,无法在嵌套函数中挂起此协程
  • 异步代码必须都有对应的关键字

对称协程与非对称协程

  • 对称协程 Symmetric Coroutine:任何一个协程都是相互独立且平等的,调度权可以在任意协程之间转移。
  • 非对称协程 Asymmetric Coroutine:协程出让调度权的目标只能是它的调用者,即协程之间存在调用和被调用关系。

对称协程提供了更高的并发性和灵活性,适合需要高并发处理的场景;而非对称协程则在某些控制流固定的场景下更为适用。

相关文章:

协程2 --- 相关概念

文章目录 协程切换方案协程库的完善程度协程栈方案协程调度实现有栈协程与无栈协程对称协程与非对称协程 协程切换方案 具体使用和解析看栈切换那个博客 使用setjump、longjump c语言提供的方案 可参考:libmill 使用操作系统提供的api:ucontext、fiber …...

Hadoop-005-HDFS分布式文件存储原理

一、HDFS数据如何存储 分布式存储:每个服务器(节点)存储文件的一部分, 本文提到的part只是为方便理解, 指的文件部分数据, 并不是真实存在的概念 #mermaid-svg-qjJMG6r2bzRNcWkF {font-family:"trebuchet ms",verdana,arial,sans-s…...

【多线程入门篇】 创建线程以及线程的属性

大家好呀 我是浪前 今天给大家讲解的是创建线程以及线程的属性 祝愿所有点赞关注的人,身体健康,一夜暴富,升职加薪迎娶白富美!!! 点我领取迎娶白富美大礼包 🍓多线程编程: 前言: 我们为什么不用多进程?…...

三十四、Python基础语法(文件操作-上)

一、介绍 文件:可以储存在长期储存设备上的一段数据,在计算机储存的数据都是二进制的形式储存的,我们用软件打开文件不是看见0和1是因为软件会自动将二进制数据进行转换。 二、文件操作 1.打开文件 打开文件:文件是在硬盘中储…...

【大咖云集,院士出席 | ACM独立出版】第四届大数据、人工智能与风险管理国际学术会议 (ICBAR 2024,11月15-17日)--冬季主会场

第四届大数据、人工智能与风险管理国际学术会议 (ICBAR 2024)--冬季主会场 2024 4th International Conference on Big Data, Artificial Intelligence and Risk Management 官方信息 会议官网:www.icbar.net 2024 4th International Conference on Big Data, Art…...

03 Oracle进程秘籍:深度解析Oracle后台进程体系

文章目录 Oracle进程秘籍:深度解析Oracle后台进程体系一、Oracle后台进程概览1.1 DBWn(Database Writer Process)1.2 LGWR(Log Writer Process)1.3 SMON(System Monitor Process)1.4 PMON&#…...

AndroidStudio通过Bundle进行数据传递

作者:CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境:AndroidStudio 目录 1.新建活动 2.修改页面布局 代码: 效果: 3.新建类ResultActivity并继承AppCompatActivity 4.新建布局文件activity_result.xml 代…...

Linux篇(文件管理命令)

目录 一、Linux下文件命名规则 1. 可以使用哪些字符 2. 文件名的长度 3. 文件名的大小写 4. Linux文件扩展名 二、目录创建与删除 1. 目录创建 1.1. mkdir创建目录 1.2. mkdir -p 递归创建目录 1.3. 使用mkdir同时创建多个目录 2. 目录删除(必须是空目录&…...

大数据新视界 -- 大数据大厂之 Impala 性能优化:数据存储分区的艺术与实践(下)(2/30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

【数据结构】B树

B树(B-Tree)是一种自平衡的多叉搜索树,广泛应用于数据库系统和文件系统中,以便高效地进行数据存储和检索。它的设计目标是减少磁盘I/O操作,使得在大量数据的情况下依然能够进行快速的查找、插入和删除操作。 B树的特点…...

Docker 容器网络模式详解

Docker 容器网络模式详解 1.1 引言 1.1.1 Docker 网络简介 Docker 是一个开源的应用容器引擎,它允许开发者将应用和依赖打包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器采用沙箱机制,彼此…...

吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)4.11

目录 第四门课 卷积神经网络(Convolutional Neural Networks)第四周 特殊应用:人脸识别和神经风格转换(Special applications: Face recognition &Neural style transfer)4.11 一维到三维推广(1D and 3…...

小游戏开发,出现了降本增效的技术?

中国经济下行大周期下,要说受影响程度较小的,非游戏行业莫属了。 小游戏的快速增长主要得益于其便捷的使用方式和轻量化的特点。小游戏通常无需下载,即点即玩,适合在碎片时间内进行娱乐,这种特性吸引了大量用户。此外…...

(4)Java 编程基础概览:Java中的输入输出操作与代码注释详解

目录 1. 控制台输出操作2. 控制台输入操作代码解释:3. 代码注释3.1 单行注释3.2 多行注释3.3 文档注释3.4 注释的重要性3.5 注意事项在Java编程语言中,输入与输出(I/O)操作扮演着举足轻重的角色。它们允许程序与外界环境进行数据的交互,无论是从用户处获取信息,还是向用户…...

Git使用指南

目录 工作机制基本框架:流程图 基本命令分支操作远程仓库本地仓库关联远程仓库 参考 工作机制 基本框架: Workspace:开发者工作区,也就是你当前写代码的目录,它一般保持的是最新仓库代码。Index / Stage:暂存区,最早…...

【linux】再谈网络基础(一)

1. 再谈 "协议" 协议是一种 "约定",在读写数据时, 都是按 "字符串" 的方式来发送接收的. 但是这里我们会遇到一些问题: 如何确保从网上读取的数据是否是完整的,区分缓冲区中的由不同客户端发来的数据 2. 网…...

Unknown at rule @tailwindscss(unknownAtRules)

一、前言 整合 tailwindcss 后,发现指令提示警告 Unknown at rule tailwindscss(unknownAtRules),其实是 vscode 无法识别 tailwindscss 指令,不影响使用,但是对于我这种有编程洁癖的人来说,有点膈应。 二、解决方案…...

IDEA - 快速去除 mapper.xml 黄色警告线和背景色----简化版

1.打开设置 2.去掉黄色警告线设置 3.去掉背景色设置 4.示范图...

高级 SQL 技巧详解

文章目录 高级 SQL 技巧详解一、引言二、窗口函数1、窗口函数的使用1.1、RANK() 函数示例1.2、常用窗口函数 三、公共表表达式(CTE)2、CTE 的使用2.1、CTE 示例 四、索引优化3、索引的创建与优化3.1、创建索引3.2、索引类型与注意事项 五、事务管理4、事…...

移除元素(java)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作: 更改…...

华为云AI开发平台ModelArts

华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

【Oracle APEX开发小技巧12】

有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...

CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx

“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网&#xff08;IIoT&#xff09;场景中&#xff0c;结合 DDS&#xff08;Data Distribution Service&#xff09; 和 Rx&#xff08;Reactive Extensions&#xff09; 技术&#xff0c;实现 …...

表单设计器拖拽对象时添加属性

背景&#xff1a;因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...