协程2 --- 相关概念

news2024/11/7 23:10:49

文章目录

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

协程切换方案

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

  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:协程出让调度权的目标只能是它的调用者,即协程之间存在调用和被调用关系。

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

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

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

相关文章

杨传辉:云+AI 时代的一体化数据库|OceanBase发布会实录

在 2024 OceanBase 年度发布会 上, OceanBase CTO 杨传辉进行了主题为《云和 AI 时代的一体化数据库战略思考》的演讲,本文为演讲实录,欢迎阅读。 视频观看可点击:https://www.oceanbase.com/video/9001825 各位 OceanBase 的客…

04 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索

文章目录 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索一、多版本并发控制(MVCC)1.1 理论解析1.2 实践应用 二、锁与闩锁机制2.1 理论解析2.2 实践应用 三、事务隔离级别3.1 理论解析3.2 实践应用 四、死锁预防与解决…

Python-利用tkinter库编写一个exe伪恶意程序文件(下)

前言 接着上篇所讲的,我们已经完成了源代码的准备,并将其储存在了function_1.py文件中。接下来我们将把function_1.py文件编写为相对应的exe文件。那么好,废话不多说,我们直接开始。(温馨提示:由于整蛊的需…

vue使用canves把数字转成图片验证码

<canvas id"captchaCanvas" width"100" height"40"></canvas>function drawCaptcha(text) {const canvas document.getElementById(captchaCanvas);const ctx canvas.getContext(2d);// 设置背景颜色ctx.fillStyle #f0f0f0;ctx.f…

商标注册流程

个人名义&#xff08;自然人&#xff09;申请准备&#xff1a;身份证复印件(签字&#xff0c;PDF格式&#xff0c;小于2M)&#xff1b;个体户执照副本复印件(签字&#xff0c;PDF格式&#xff0c;小于2M)&#xff1b;商标图样(建议黑白JPG&#xff0c;建议尺寸800*800尺寸)。公…

《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明

参考 《element plus 使用 icon 图标(两种方式)》使用 icon 升级 Vue2 升级 Vue3 项目时&#xff0c;遇到命名时的实心与空心点差异&#xff01; ElementUI&#xff1a; 实心是 el-icon-more空心是 el-icon-more-outline ElementPlus&#xff1a; 实心是 el-icon-more-fill…

如何利用 Python 的爬虫技术获取淘宝天猫商品的价格信息?

以下是使用 Python 的爬虫技术获取淘宝天猫商品价格信息的两种常见方法&#xff1a; 方法一&#xff1a;使用 Selenium 一、环境准备&#xff1a; 安装 selenium 库&#xff1a;在命令行中运行 pip install selenium。下载浏览器驱动&#xff1a;如 ChromeDriver&#xff08;确…

Navicat for MySQL 错误:1251

mySql&#xff1a;8.4 Navicat for MySQL&#xff1a;11.0.10 企业版 绿色版 官网中关于mysql_native_password插件的说法&#xff1a;链接 1. 问题 连接数据库报错&#xff1a;1251 要求升级Navicat for MySQL 2. 原因 mysql中的mysql_native_password插件默认是关闭的 …

Android 如何写代码更少出现bug?借助IDE的检测代码质量插件来解决。

目录 前言 大家好呀~&#xff0c;我是前期后期&#xff0c;在网上冲浪的一名程序员&#xff0c;分享一些自己学到的知识&#xff0c;希望能够帮助大家节省时间。 如何写代码更少出现bug&#xff1f; 很多一些人可能会推荐我们&#xff0c;多看一些阿里巴巴的规范&#xff0c…

洛谷 P2113 看球泡妹子(DP)

传送门https://www.luogu.com.cn/problem/P2113 解题思路 可以设 表示前 场比赛看了 场&#xff0c;小红的满足度为 的最大精彩度。 然后可以枚举前面的一个比赛 &#xff0c;可以得到转移方程&#xff1a; 但是&#xff0c;我们发现数组空间有一点小大&#xff0c;可以…

HTAP数据库国产化改造技术可行性方案分析

一、现状及需求痛点 当前地市统一支撑平台是为地市租户提供全方位业务支持的核心系统&#xff0c;以满足地市级用户在业务处理、数据分析、用户服务及内部管理等多方面的需求。主要承载业务系统的联机事务处理&#xff08;OLTP&#xff09;与联机分析处理&#xff08;OLAP&…

ELK-ELK基本概念_ElasticSearch的配置

文章目录 一、什么是ELK&#xff1f;有什么用&#xff1f;ELK是什么&#xff1f;ElasticsearchLogstashKibana ELK的作用 二、ElasticSearch的安装与基本配置为何需要依赖JDK&#xff1f;使用yum install java-11-openjdk和使用Oracle官网提供的jdk的rpm包安装JDK的区别 参考资…

OpenAI大事记;GPT到ChatGPT参数量进化

目录 OpenAI大事记 GPT到ChatGPT参数量进化 OpenAI大事记 GPT到ChatGPT参数量进化 ChatGPT是从初代 GPT逐渐演变而来的。在进化的过程中,GPT系列模型的参数数量呈指数级增长,从初代GPT的1.17亿个参数,到GPT-2的15 亿个参数,再到 GPT-3的1750 亿个参数。模型越来越大,训练…

DDD领域分析

DDD领域分析是一种对现实业务进行建模分析的一种方法&#xff0c;它对业务问题做了分类&#xff0c;分层与抽象&#xff0c;为后面代码的编写理清了思路。 如何理解DDD呢&#xff1f;首先DDD中有许多名称&#xff0c;我这里一一列举出来&#xff1a;领域&#xff0c;子域&…

ES集群搭建(仅供自己参考)

单节点问题&#xff1a;单机的elasticsearch做数据存储&#xff0c;面临的两个问题&#xff1a;海量的数据存储问题、单节点故障。 一个节点存储的数据是有限的。 海量数据存储问题&#xff1a;将索引库从逻辑上拆分为N个分片&#xff08;shard&#xff09;&#xff0c;存储到…

【测试工具篇一】全网最强保姆级教程抓包工具Fiddler(2)

本文接上篇Fiddler介绍&#xff0c;开始讲fiddler如何使用之前&#xff0c;给大家讲讲http以及web方面的小知识&#xff0c;方便大家后面更好得理解fiddler使用。 目录 一、软件体系结构---B/S与C/S架构 B/S架构 C/S架构 二、HTTP基础知识 什么是http请求和响应? http协…

诗林工作室(编号:mb0003)分享:Finbiz自适应响应式网页设计模版,适用于前端设计、博客、官网等多类型开发模版

本设计模版来自外网&#xff0c;为HTML类型的模版&#xff0c;色彩多样&#xff0c;适合Web开发人员做前端站点设计参考使用。全站模版倾向于官网设计、自主博客等多行业的平台模版开发&#xff0c;适合各大CMS的主题模版开发参考&#xff0c;如常见的Wordpress主题开发、Z-Blo…

2-142【软件无线电原理与应用作业】基于matlab的圆形阵列的波束形成进行仿真

【软件无线电原理与应用作业】基于matlab的圆形阵列的波束形成进行仿真&#xff0c;具有14页文档。假设发射信号载频为1GHz&#xff0c;圆形阵列半径为0.8米&#xff0c;在圆周上均匀布置30个阵元。1.画出指向0度的方向图。2.如果目标在0度&#xff0c;有一不相干的干扰信号在3…

[CUDA] 设置sync模式cudaSetDeviceFlags

文章目录 1. 设置cuda synchronize的等待模式2 设置函数3. streamQuery方式实现stream sync等待逻辑Reference 1. 设置cuda synchronize的等待模式 参考资料&#xff1a;https://docs.nvidia.com/cuda/pdf/CUDA_Runtime_API.pdf cuda的 synchronize等待模式分为&#xff1a; Y…

[OS]vma? trap? Sys_mmap根据思路来实现!!

// Defined in user.hvoid *mmap(void *addr, size_t length, int prot, int flags, int fd, off_toffset);// TODO: kernel mmap executed in sysfile.cuint64sys_mmap(void){}#define VMASIZE 16struct vma {uint64 addr; // 映射的虚拟地址起始位置int len; …