C++20协程
目录
协程原理:
进程、线程和协程的区别和联系编辑
协程在IO多路复用中
协程的目的:
协程的优势:
协程原理:
(学习来源:幼麟实验室)
线程是进程中的执行体,拥有一个执行入口,以及从进程虚拟地址空间中分配的栈,包括用户栈和内核栈。
操作系统会记录线程控制信息,而线程获得CPU时间片以后才可以执行,此时CPU中的栈指针、指令指针等寄存器都要切换到对应的线程。
如果线程有创建几个执行体,给他们指定各自的执行入口,申请一些内存给他们用作执行栈,那么线程就可以按需调度这几个执行体了,为了实现这几个执行体的切换,线程也需要记录他们的控制信息(id、栈的位置、执行入口地址、执行现场)线程可以选择一个执行体来执行,此时CPU中指令指针就会指向这个执行体的执行入口,栈基和栈指针寄存器也会指向线程给它分配的执行栈。
要切换执行体时, 需要保存当前执行体的执行现场,然后切换到另外一个执行体,通过一样的方式也可以恢复到之前的执行体,这样就可以从上次中断的地方继续执行。
这些由线程创建的执行体就是协程。因为用户程序不能操作内核空间,所以只能给协程分配用户栈,而操作系统对协程一无所知,所以协程又被称为用户态线程。
创建协程时,都要指定执行入口,底层都会分配协程执行栈和控制信息,用于实现用户态的调度,让出执行权时也要保存执行现场,用于从中断处恢复执行。协程思想的关键在于控制流的主动让出和恢复。
每个协程拥有自己的执行栈,可以保存自己的执行现场。可以由用户程序按需要创建协程,协程主动让出执行权时,会保存执行现场,然后切换到其他协程,协程恢复执行时,会根据之前保存的执行现场恢复到中断前的状态继续执行,这样就通过协程实现了即轻量级又灵活的,由用户态进行调度的多任务模型。
进程、线程和协程的区别和联系
协程在IO多路复用中
通过操作系统记录的进程控制信息,打开文件描述符表,进程打开的文件、创建的socket等等都在这个表里。socket的所有操作都由操作系统来提供,通过系统调用来完成,每创建一个socket都会在对应打开的文件描述符表中添加一个记录,而返回给应用程序的只有一个socket描述符,用于识别不同的socket。
每个TCP socket在创建时,操作系统都会给他分匹配一个读缓冲区和一个写缓冲区,要获得响应数据就需要从内核的读缓冲区拷贝到用户空间的接收数据,同样的要通过socket发送数据也要先放到写缓冲区中。
问题:用户程序想要接收数据时,读缓冲区不一定有数据,发送数据时,写缓冲区不一定有空间?
①:阻塞式IO:让出CPU进到等待队列中,等socket就绪后再次获得时间片才可继续执行,处理一个socket就要占用一个线程。
②:非阻塞式IO:不需要让出CPU,但是需要频繁的检查socket是否就绪了,这是一种忙等待的方式,很难把握轮询的间隔时间,容易造成空耗CPU,加剧响应延迟
③:IO多路复用:操作系统提供支持,把需要等待的socket加入到监听集合,这样就可以通过一次系统调用,同时监听多个socket,有socket就绪了就可以逐个处理了,既不为等待某个socket而阻塞也不会陷入忙等待之中。
select:支持可读、可写、异常三类事件
可以设置要监听的描述符,也可以设置等待时间,当有准备好的fd或者超过等待时间select就会返回,最多可以监听1024(fs_Set是个unsigned long型的数据,16个元素),
等待有事件就绪或超时:每次调用select都要传递所有的监听集合,需要频繁的从用户态到内核态拷贝数据。
判断那个fd就绪:每次需要遍历所有集合
poll: 相比于select没有文件描述符数量限制,fd数目等于最多可打开的文件描述符个数
任然有每次调用poll都要从用户态到内核态拷贝,遍历集合找就绪fd
epoll:没有这些问题
epoll_create :创建epoll 获取句柄 创建一个白板 存放fd_events。
epoll_ctl :添加或者删除fd对应的事件信息,用于向内核注册新的描述符或者是改变某个文件描述符的状态。已注册的描述符在内核中会被维护在一棵红黑树上。
除了指定fd和要监听的事件类型(EPOLLIN、EPOLLOUT等)还可以传入event_data:按需要定义一个数据结构用于处理对应的fd,每次只需要传入要操作的一个fd,无需传入所有监听集合,而且只需要注册一次。
epoll_wait:通过该函数得到的fd都是已经就绪的,不需要再遍历监听集合了 通过回调函数内核会将 I/O 准备好的描述符加入到一个链表中管理,
两种触发模式:
LT:水平触发
当 epoll_wait() 检测到描述符事件到达时,将此事件通知进程,进程可以不立即处理该事件,下次调用 epoll_wait() 会再次通知进程。是默认的一种模式,并且同时支持 Blocking 和 No-Blocking。
ET:边缘触发
和 LT 模式不同的是,通知之后进程必须立即处理事件。
下次再调用 epoll_wait() 时不会再得到事件到达的通知。很大程度上减少了 epoll 事件被重复触发的次数,因此效率要比 LT 模式高。只支持 No-Blocking,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。在ET模式下,当进程没有及时处理时,只有再下次该文件描述符上再发生事件时才会得到事件通知。
问题:假如一个socket可读了,但是只读到了半条请求,也就是说需要再次等待这个socket可读,再继续处理下一个socket之前,需要记录下这个socket的处理状态,下一次这个socket可读时,也需要恢复上次保存的现场。也就是说再IO复用中是实现业务逻辑时,我们需要随着事件的等待和就绪而平凡的保存和恢复现场。适合使用协程
在IO多路复用这里, 事件循环依然存在,依然要在循环中逐个处理就绪的fd,但处理过程却不是围绕具体业务而是面向协程调度。
如果是用于监听端口的fd就绪了,就建立连接创建一个新的fd,交给一个协程来处理,协程执行入口就指向业务处理函数入口,业务处理过程中需要等待时就注册IO事件,然后让出,这样执行权就会切换到该协程的地方继续执行。
如果是其他等待IO事件的fd就绪了,只需要恢复关联的协程即可,协程拥有自己的栈,要保存和恢复现场都很容易实现。
IO多路复用这一层的事件循环就和具体的业务逻辑解耦了,可以把res,write,connect等可能要等待的函数包装一下,在其中实现IO事件的注册与主动让出,这样就可以在业务逻辑层面使用这些包装函数按照常规的顺序来实现业务逻辑了
这写包装函数在需要等待时会注册IO事件,然后让出协程,这样在我们实现业务逻辑时完全不用关心保存与恢复现场的问题了,协程与IO多路复用的结合保存了IO多路复用的高并发性能还解放了业务逻辑的实现。
协程的目的:
协程主要是用来编写异步逻辑的,在有协程之前想要异步做并发要么要开多线程、要么要写函数回调非阻塞的代码。
协程的优势: 
协程切换开销比线程开销小百倍,协程可以在单线程上轻松实现并发任务。
相关文章:

C++20协程
目录 协程原理: 进程、线程和协程的区别和联系编辑 协程在IO多路复用中 协程的目的: 协程的优势: 协程原理: (学习来源:幼麟实验室) 线程是进程中的执行体,拥有一个…...
Zabbix 6.0 监控其他
文章目录 一、Zabbix 监控 Windows 系统1)下载 Windows 客户端 Zabbix agent 22)安装客户端,配置3)在服务端 Web 页面添加主机,关联模板 二、Zabbix 监控 java 应用1)客户端开启 java jmxremote 远程监控功…...
Django rest_framework Serializer中的create、Views中的create/perform_create的区别
Django rest_framework Serializer中的create、Views中的create/perform_create的区别 对于后端来说,前后端分离的方式能让前后端的开发都爽。和所有的爽一样,每爽一次都要付出一定的代价。而前后端分离的代价,就是后端要面对巨量的模块化的功…...

差异性分析傻瓜版
path1输入你的第一个Excel path2输入你的第二个Excel DEG.dig <- function(path1,path2) { require(xlsx) require(tidyverse) require(limma) require(edgeR) E<- read.xlsx (path1,sheetIndex 1,header 1) %>% column_to_rownames(var &…...

Keystone Automotive EDI 需求分析
Keystone Automotive 是一家知名的汽车零部件销售卖场,自创立以来,在汽车行业取得了卓越的成就。作为一家专业的汽车零部件供应商,Keystone Automotive 致力于为客户提供优质的产品和卓越的服务。公司的经营范围涵盖广泛,涉及多个…...

jmeter创建一个压测项目
1.jemeter新建一个项目: 2.接下来对Thread进行描述,也可以先使用默认的Thread进行操作。 3.添加http请求头的信息。按照如图所示操作 4.在请求头里面添加必要的字段,可以只填必要字段就可以 5.添加Http请求信息,如下图ÿ…...

CEC2013(MATLAB):淘金优化算法GRO求解CEC2013的28个函数
一、淘金优化算法GRO 淘金优化算法(Gold rush optimizer,GRO)由Kamran Zolf于2023年提出,其灵感来自淘金热,模拟淘金者进行黄金勘探行为。淘金优化算法(Gold rush optimizer,GRO)提…...

AI Deep Reinforcement Learning Autonomous Driving(深度强化学习自动驾驶)
AI Deep Reinforcement Learning Autonomous Driving(深度强化学习自动驾驶) 背景介绍研究背景研究目的及意义项目设计内容算法介绍马尔可夫链及马尔可夫决策过程强化学习神经网络 仿真平台OpenAI gymTorcs配置GTA5 参数选择行动空间奖励函数 环境及软件…...
Java super
在Java中,关键字"super"用于引用一个类的父类。它可以有以下几种用法: 1. 访问父类成员:通过使用"super"后跟一个点,你可以从子类中访问父类的成员(方法或字段)。当子类重写一个方法或…...

【人工智能前沿弄潮】——生成式AI系列:Diffusers学习(1)了解Pipeline 、模型和scheduler
Diffusers旨在成为一个用户友好且灵活的工具箱,用于构建针对您的用例量身定制的扩散系统。工具箱的核心是模型和scheduler。虽然DiffusionPipeline为了方便起见将这些组件捆绑在一起,但您也可以拆分管道并单独使用模型和scheduler来创建新的扩散系统。 …...
TypeScript 非空断言
TypeScript 非空断言 发布于 2020-04-08 15:20:15 17.5K0 举报 一、非空断言有啥用 介绍非空断言前,先来看个示例: function sayHello(name: string | undefined) {let sname: string name; // Error } 对于以上代码,TypeScript 编译器…...

Python编程——谈谈函数的定义、调用与传入参数
作者:Insist-- 个人主页:insist--个人主页 本文专栏:Python专栏 专栏介绍:本专栏为免费专栏,并且会持续更新python基础知识,欢迎各位订阅关注。 目录 一、理解函数 二、函数的定义 1、语法 2、定义一个…...

在Ubuntu中使用Docker启动MySQL8的天坑
写在前面 简介: lower_case_table_names 是mysql设置大小写是否敏感的一个参数。 1.参数说明: lower_case_table_names0 表名存储为给定的大小和比较是区分大小写的 lower_case_table_names 1 表名存储在磁盘是小写的,但是比较的时候是不区…...
Python3.x String内置函数大全
文章目录 总结一下Python3.x字符串的常用系统函数,总共分为8类1. 大小写字母转换类的函数str.capitalize()str.title()str.lower()str.upper()str.swapcase() 2. 统计类的函数str.count(str1, beg 0,endlen(string)) 3. 匹配类的函数str.endswith(suffix, beg0, end…...

Go异常处理机制panic和recover
recover 使用panic抛出异常后, 将立即停止当前函数的执行并运行所有被defer的函数,然后将panic抛向上一层,直至程序crash。但是也可以使用被defer的recover函数来捕获异常阻止程序的崩溃,recover只有被defer后才是有意义的。 func main() { p…...

QMainwindow窗口
QMainwindow窗口 菜单栏在二级菜单中输入中文的方法给菜单栏添加相应的动作使用QMenu类的API方法添加菜单项分隔符也是QAction类 工具栏状态栏停靠窗口 菜单栏 只能有一个, 位于窗口的最上方 关于顶级菜单可以直接在UI窗口中双击, 直接输入文本信息即可, 对应子菜单项也可以通…...
P5735 【深基7.例1】距离函数
题目描述 给出平面坐标上不在一条直线上三个点坐标 ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) (x_1,y_1),(x_2,y_2),(x_3,y_3) (x1,y1),(x2,y2),(x3,y3),坐标值是实数,且绝对值不超过 100.00,求围成的三角形周长。保留两…...

prometheus告警发送组件部署
一、前言 要实现Prometheus的告警发送需要通过alertmanager组件,当prometheus触发告警策略时,会将告警信息发送给alertmanager,然后alertmanager根据配置的策略发送到邮件或者钉钉中,发送到钉钉需要安装额外的prometheus-webhook…...

CAPL - XML和TestModule结合实现测试项可选
目录 目的:是否想实现如下面的功能呢? 一、.can和.cin文件中函数开发...
Latex安装与环境配置(TeXlive、TeXstudio与VS code的安装)编译器+编辑器与学习应用
TeXlive 配置Tex排版系统需要安装编译器+编辑器。TeX 的源代码是后缀为 .tex 的纯文本文件。使用任意纯文本编辑器,都可以修改 .tex 文件:包括 Windows 自带的记事本程序,也包括专为 TeX 设计的编辑器(TeXworks, TeXmaker, TeXstudio, WinEdt 等),还包括一些通用的文本编…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...

【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...

理想汽车5月交付40856辆,同比增长16.7%
6月1日,理想汽车官方宣布,5月交付新车40856辆,同比增长16.7%。截至2025年5月31日,理想汽车历史累计交付量为1301531辆。 官方表示,理想L系列智能焕新版在5月正式发布,全系产品力有显著的提升,每…...