协程2 --- 相关概念
文章目录
- 协程切换方案
- 协程库的完善程度
- 协程栈方案
- 协程调度实现
- 有栈协程与无栈协程
- 对称协程与非对称协程
协程切换方案
具体使用和解析看栈切换那个博客
-
使用
setjump、longjump
c语言提供的方案
可参考:libmill -
使用操作系统提供的api:
ucontext、fiber
这种方式是最安全可靠的,但是性能比较差。
可参考:libtask -
自己写汇编码实现
这种方式的性能可以很好,但是不同系统、甚至不同版本的linux都需要不同的汇编码,兼容性奇差无比。
可参考:libco -
使用
boost
coroutine、context等性能很好,boost也帮忙处理了各种平台架构的兼容性问题,不过需要依赖boost框架。
可参考:libgo
协程库的完善程度
-
API级
实现协程上下文切换api,或添加一些便于使用的封装。
如:boost.context,boost.coroutine问题:
没有协程调度 -
玩具级
实现了协程调度,无需用户手动处理协程上下文切换。
如:libmill问题:
没有HOOK,只实现了一套网络io相关函数,这也意味着涉及网络的第三方库全部不可用了。 -
工业级
以部分正确的方式HOOK了网络io相关的syscall,可以少改甚至不改代码的兼容大多数第三方库。
如:libco问题:
没有完整生态,协程间通讯、协程同步、调试等机制不够完善。未能完全模拟syscall的行为,只能兼容行为符合预想的同步模型的第三方库,只能覆盖一部分的第三方库。 -
框架级
以100%行为模拟的方式HOOK了网络io相关的syscall,可以完全不改代码兼容大多数第三方库。
如:libgo问题:由于C++的灵活性,
用户行为是不受限的,所以依然存在几个边边角角的难点需要开发者注意:没有gc,TLS的问题,用户不按套路出牌、把逻辑代码run在协程之外,粗粒度的线程锁等等。 -
语言级
语言级的协程实现
如:golang开发者的一切行为都是
受限行为,可以实现无死角的完善的协程。
c++20也支持协程了
协程栈方案
-
静态栈
栈大小固定,有大小难以权衡的问题。
设置大了,会造成浪费。
设置小了,会有栈溢出问题。 -
分段栈
GCC支持一种允许栈内存不连续的编译参数,实现原理是在每个函数调用开头都插入一段栈内存检测的代码,如果栈内存不够用了就申请一块新的内存,作为栈内存的延续。
但是第三方库没有使用这种方式来编译,那就无法在其中检测栈内存是否需要扩展,栈溢出的风险很大。 -
拷贝栈
每次检测到栈内存不够用时,申请一块更大的新内存,将现有的栈内存copy过去,就像std::vector那样扩展内存。
但C/C++是有指针的,栈内存的copy会导致指向其内存地址的指针失效;又因为其指针的灵活性,修改对应的指针成为了一种几乎不可能实现的事情。 -
共享栈(libco)
申请一块大内存作为共享栈(比如8MB),每次协程挂起时计算协程栈真正使用的内存,copy到私有栈中;唤醒协程时,把协程私有栈的内存copy到共享栈中,这样每次只需保存真正使用到的栈内存量即可。
这种方案极大程度上避免了内存的浪费,做到了用多少占多少,同等内存条件下,可以启动的协程数量更多,但是协程切换慢,还有引用失效问题。 -
虚拟内存栈(libgo)
申请的内存并不会立即被映射成物理内存,而是仅管理于虚拟内存中,真正对其读写时才会触发缺页中断,分配物理内存;而且基本上是按页递增分配。
协程调度实现
-
栈式调度(libco)
栈式调度是典型的不公平调度。协程队列是一个栈式的结构,每次创建的协程都置于栈顶,并且会立即暂停当前协程并切换至子协程中运行,子协程运行结束(或其他原因导致切换出来)后,继续切换回来执行父协程;越是处于栈底部的协程(越早创建的协程),被调度到的机会就越少。 -
星切调度(libgo)
调度线程 -> 协程A -> 调度线程 -> 协程B -> 调度线程 -> …
调度线程居中,协程在周围,调度顺序图看起来就像是星星一样,称为星切。
将当前可调度的协程组织成先进先出的队列(runnable list),顺序pop出来做调度;新创建的协程排入队尾,调度一次后如果状态依然是可调度(runnable)的协程则排入队尾,调度一次后如果状态变为阻塞,那阻塞事件触发后也一样排入队尾,是为公平调度。 -
环切调度
调度线程 -> 协程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,要通过此题,您需要执行以下操作: 更改…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
