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

重写Sylar基于协程的服务器(3、协程模块的设计)

重写Sylar基于协程的服务器(3、协程模块的设计)

重写Sylar基于协程的服务器系列:

重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar)

重写Sylar基于协程的服务器(1、日志模块的架构)

重写Sylar基于协程的服务器(2、配置模块的设计)

重写Sylar基于协程的服务器(3、协程模块的设计)

前言

关于线程以及线程并发的封装在此略过,该部分比较简单,有兴趣的朋友可以看一下我原来写的Muduo的博客:muduo源码阅读笔记(2、对C语言原生的线程安全以及同步的API的封装)、muduo源码阅读笔记(3、线程和线程池的封装),或者直接阅读本文配套的简化版sylar的源码:https://github.com/LunarStore/lunar。

协程模块的设计与实现

协程的状态定义

协程分为:初始化状态、执行状态、阻塞状态、就绪状态、结束状态、异常状态。定义如下:

enum State{INIT,   // 初始化EXEC,   // 执行HOLD,   // 阻塞READY,  // 就绪TERM,   // 结束EXCE    // 异常
};

协程的状态机

任务协程:

一个任务协程运行时,可能的状态机图,如下图:

任务协程的状态机

可能跟着协程调度模块、io协程调度模块走一遍调度任务协程的流程后,才能清晰的理解该图的意义,这里可以先以整体的视角,看一看一个任务协程的状态切换时机即可。笔者能力有限,不足的地方可以在评论区指出

调度协程&&Idle协程:

正常情况下,调度协程和Idle协程的状态机如下图:

调度协程和Idle协程的状态机

协程模块的设计如下

总体来讲,协程模块(Fiber类)主要就是对ucontext_t提供的getcontext、makecontext、swapcontext等函数做了一个封装,为了简化后续调度模块使用协程。要讲清楚协程模块,不得不引入类型为Finer::ptr(就是Fiber对象的智能指针)三个重要的线程全局变量,分别是:线程原始协程(t_threadFiber)、线程当前正在运行的协程(t_fiber)、调度协程(t_scheRunFiber),这三个全局变量在每个线程中都会拥有一份,独立于其他线程。由于引入了协程的概念,我们就应该弱化线程的概念,以一切皆是协程的思想去编写代码。所以一个线程在被创建时,它原始的上下文就可以作为一个协程,我们把它的上下文保存在t_threadFiber中,这样可以待线程的其他协程执行完毕,再切换回来。具体类的设计如下:

  1. 构造函数,用户在构造一个协程时,会传入协程的回调函数、协程堆栈大小、指明协程在切入去执行时是和哪个协程做切换(t_threadFiber或者t_scheRunFiber),这里额外再解释一下,因为一个协程的切入可以看成是在另一个协程中进行的,所以一个协程在切入执行前,首先要保存先前协程的上下文,因为我们实现的协程服务器是有调度器的,而且每个线程会执行调度协程进行任务协程的调度,所以,一般任务协程在切入执行前,是要先将上下文保存在t_scheRunFiber中,再将上下文修改成任务协程的上下文。待任务协程执行完毕或者阻塞,再反向操作,先将上下文保存到任务协程中,再将上下文还原成t_scheRunFiber去调度其他协程。
    协程初始化首先会调用getcontext初始化m_ctx成员变量,该成员变量是保存协程的上下文核心数据结构,然后调用makecontext将协程上下文设置成静态成员函数MainFun,在静态成员函数MainFun中,会通过线程局部变量t_fiber(切入时设置)获取到协程当前运行的协程对象,进而回调用户传来的call back函数。

  2. 协程默认构造,该构造是私有化的,专门为线程原始的协程打造,内部只调用getcontext函数。

  3. swapIn成员函数,根据用户指定调用swapcontext,和t_threadFiber做切换或者和t_scheRunFiber做切换。

    协程切入伪代码:

    伪代码

  4. swapOut成员函数,协程切换回t_threadFiber或t_scheRunFiber时使用,也是调用swapcontet。

    协程切出伪代码:

    伪代码

  5. yieldToHold/yieldToReady,设置协程状态然后调用swapOut。


下一章将介绍协程调度模块

感兴趣的同学,可以阅读一下本文实现的源码:https://github.com/LunarStore/lunar


本章完结

相关文章:

重写Sylar基于协程的服务器(3、协程模块的设计)

重写Sylar基于协程的服务器(3、协程模块的设计) 重写Sylar基于协程的服务器系列: 重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar) 重写Sylar基于协程的服务器(1、日志模…...

Linux之系统安全与应用续章

目录 一. PAM认证 1.2 初识PAM 1.2.1 PAM及其作用 1.2.2 PAM认证原理 1.2.3 PAM认证的构成 1.2.4 PAM 认证类型 1.2.5 PAM 控制类型 二. limit 三. GRUB加密 /etc/grub.d目录 四. 暴力破解密码 五. 网络扫描--NMAP 六. 总结 一. PAM认证 1.2 初识PAM PAM是Linux系…...

《HTML 简易速速上手小册》第7章:HTML 多媒体与嵌入内容(2024 最新版)

文章目录 7.1 在HTML中嵌入视频和音频7.1.1 基础知识7.1.2 案例 1&#xff1a;嵌入视频文件7.1.3 案例 2&#xff1a;嵌入音频文件7.1.4 案例 3&#xff1a;创建一个视频和音频混合的播放列表 7.2 使用 <iframe> 嵌入外部内容7.2.1 基础知识7.2.2 案例 1&#xff1a;嵌入…...

【CSS】移动端适配

移动端适配怎么做&#xff1f; 适配的目的是在屏幕大小不同的终端设备拥有统一的界面&#xff0c;让拥有更大屏幕的终端展示更多的内容。 meta viewport (视口) 移动端初始视口的大小默认是980px&#xff0c;因为世界上绝大多数PC网页的版心宽度为980px &#xff0c;如果网页…...

DFS剪枝算法经典题目-挑选

4954. 挑选 - AcWing题库 给定一个包含 n 个正整数 a1,a2,…,an的集合。 集合中可能存在数值相同的元素。 请你从集合中挑选一些元素&#xff0c;要求同时满足以下所有条件&#xff1a; 被选中元素不少于 2 个。所有被选中元素之和不小于 l 且不大于 r。所有被选中元素之中最大…...

考研经验总结——考试期间

文章目录 一、订房二、看考场三、休息四、考前带宾馆的书五、安全 一、订房 我刚刚看了看&#xff0c;是9.10号订的酒店。你们可以提前向学长学姐打听你的考场在哪个学校&#xff08;徐州的考生&#xff0c;考省外的学校是在矿大考试&#xff0c;考省内的学校是在江师大&#…...

vue3 源码解析(6)— lifecycle 生命周期的实现

前言 对于 vue3 的生命周期&#xff0c;我们经常性会去疑问&#xff0c;生命周期有哪些呢&#xff0c;它是怎么去实现的&#xff0c; 又是什么时候调用的。 vue3 生命周期有哪些 下面这个表格列出了所有选项式api生命周期钩子和组合式api生命周期钩子&#xff0c;以及他们的…...

three.js CSS2DRenderer、CSS2DObject渲染HTML标签

有空的老铁关注一下我的抖音&#xff1a; 效果&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red;position: relative;"><…...

SECS/GEM300和半导体e84控制器

SECS&#xff08;SEMI EQUIPMENT COMMUNICATIONS STANDARD 2&#xff09;半导体设备通讯标准 GEM&#xff08;Generic Equipment Model&#xff09;定义了Fab中各个场景下设备行为及其所使用SECS消息。 GEM300也称为300mm标准&#xff0c;FAB是12寸设备的处理作业规范。主要包…...

k8s二进制及负载均衡集群部署详解

目录 常见部署方式 二进制部署流程 环境准备 操作系统初始化配置 关闭防火墙 配置SELinux 关闭SWAP 根据规划设置主机名 在master添加hosts&#xff0c;便于主机名解析 调整内核参数 配置时间同步 部署docker引擎 在所有node节点部署docker引擎 部署etcd集群 签发…...

【Django开发】0到1开发美多商城项目第3篇:用户注册业务实现(附代码,已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目&#xff08;4.0版本&#xff09;含代码和文档。功能包括前后端不分离&#xff0c;方便SEO。采用Django Jinja2模板引擎 Vue.js实现前后端…...

免费的ppt网站分享

前言 相信大学生们深有体会&#xff0c;对于学校而言&#xff0c;好像是任何活动都需要我们做ppt&#xff0c;当你拿着自己辛苦做的ppt去展示现场的时候&#xff0c;你看到别人的ppt比你的还好&#xff0c;此时心情就是毙&#xff0c;当你知道人家不过是仅仅的1个小时不到就完成…...

基于Transformer结构的扩散模型综述

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…...

POI操作word表格,添加单元格,单元格对齐方法(不必合并单元格)

添加单元格&#xff0c;直接对row进行create新的cell&#xff0c;则会导致新创建的单元格与前面的单元格不对齐的现象。 //表格信息XWPFTable table doc.createTable();table.setWidth("100%");//第一行XWPFTableRow row0table.getRow(0);XWPFTableCell cell00row0.…...

maven代码规范检查(checkstyle、findbugs)

maven代码规范检查 前言一、使用checkstyle插件1. maven-checkstyle-plugin 介绍2. 接入方式3. 如何排除某个类、包下面的文件不进行检查使用suppressionsLocation 4. 如何关闭 二、使用findbugs插件1.findbugs-maven-plugin介绍2. 接入方式3. 如何排除某个类、包下面的文件不进…...

妙用Java反射,让代码更加优雅

最近在改公司项目bug&#xff0c;需要修改别人的代码。在读别人的源码时感觉到反射真的是能够极大的提高代码的优雅性&#xff0c;在某些特定场景能极大的简化代码的编写。因此写了这篇文章用以记录分享。 我们先还原一下场景&#xff0c;在做数据展示的时候&#xff0c;需要处…...

实习日志10

1.用户信息 1.1.在用户管理中编辑用户信息 1.2.绑定公司id 1.3.显示在页面 2.修改识别逻辑 2.1.分析 先识别&#xff0c;再判断&#xff0c;清空键把识别结果清空 2.2.写码 修改了发票识别逻辑&#xff0c;略... 3.接高拍仪 3.1.js引入报错 分析&#xff1a; 遇到的错误…...

配置alias(设置别名@)

Vite配置alias需要两步进行&#xff08;TS项目&#xff09; 1、修改vite.config.ts&#xff08;让程序支持&#xff09;2、修改tsconfig.json&#xff08;让编辑器支持&#xff09;修改vite.config.ts import { defineConfig } from vite import path from path ​ function…...

【动态规划】【数学】1388. 3n 块披萨

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1388 3n 块披萨 给你一个披萨&#xff0c;它由 3n 块不同大小的部分组成&#xff0c;现在你和你的朋友们需要按照如下规则来分披萨&#xff1a; 你挑选 任…...

CS144--Chapter0--wsl2+docker环境搭建

我的笔记本配置 荣耀magicbook16&#xff0c;容量是500G&#xff0c;芯片是R7-5800 由于笔记本容量较小&#xff0c;因此考虑这个方案&#xff0c;对于台式机用户&#xff0c;建议可以直接用虚拟机或者双系统。 前言 斯坦福官网给出的方法是用他们的镜像&#xff08;基于Ubu…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...