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

2024-02-04 15:36

本文主要是介绍重写Sylar基于协程的服务器(6、HOOK模块的设计),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

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

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

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

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

重写Sylar基于协程的服务器(5、IO协程调度模块的设计)

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

简述

HOOK模块存在的必要性:让IO系统调用,以同步写法展现出异步的性能。

hook实际上就是对系统调用API进行一次封装,将其封装成一个与原始的系统调用API同名的接口,应用在调用这个接口时,会先执行封装中的操作,再执行原始的系统调用API。本文实现的是一种利用dlsym函数实现的侵入式hook。

HOOK的实现

首先,是hook重新实现accept函数、socket函数,为了高效的cpu利用率,每个被accept函数接受的socketfd、或者socket创建的fd在返回给调用者前,都会使用fcntl函数,将其设置为非阻塞,虽然socketfd被设置成非阻塞的,但是我们的hook机制,能够利用非阻塞的socketfd实现一种在调用者看来是阻塞的socketfd。

其次,为了获取socketfd的超时时间,所有setsockop也会被hook,如果socketfd之前使用setsockop函数设置超时,其超时时间就会被fdmanager类获取,将超时时间记录在对应的fd上。当然,为了善后,close也会被hook,在调用真正close前,会唤醒相应socketfd上的所有监听协程,让协程退出。

最后,将socketIO有关的系统调用(如read、write、accept等)抽象出一个统一的接口do_io,用户在调用socketIO有关函数时,底层统一调用do_io。do_io流程如下。

  1. 进入do_io函数内部,首先会检查socketfd的合法性。

  2. 如果socketfd是合法的,就去调用fun。(fun是通过do_io参数传进来的真正的io系统调用函数地址)。

  3. 如果sockefd是非法的,也会去调用一次fun,fun返回什么,do_io就返回什么,完全依赖原始的系统底层调用对非法socketfd的处理。

  4. 对于合法的socketfd调用fun,由于socketfd是非阻塞的,不管是否读取到数据,fun都会立刻返回。如果读到数据,do_io整体就返回读到的字节数。如果没有读到数据,fun会返回-1,errno为EAGAIN,但是do_io不会返回。

  5. 然后调用线程当前的IOManager的addEvent函数,根据用户调用的socketIO相关接口对socketfd添加事件相应读写事件,在addEvent函数内部会把<当前协程,当前协程的协程调度器>放入socketfd对应的EventContext结构体里面,等待socketfd上io事件到来并由idle协程调用TrigleEvent函数唤醒当前协程。

  6. 然后调用yieldToHold将协程变成Hold状态,等待socketfd上io事件到来时idle协程将该协程唤醒。

  7. 唤醒后,首先查看是怎么被唤醒的,如果是因为超时被唤醒,do_io就返回超时的错误,如果是因为有io事件到来被唤醒,那么回到第4步。

HOOK模块核心函数do_io伪代码:

do_io伪代码

do_io的使用(也即read、write系统调用的hook)

read、write的hook

下一章将介绍TcpServer模块。

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


本章完结

这篇关于重写Sylar基于协程的服务器(6、HOOK模块的设计)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/677981

相关文章

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Nginx添加内置模块过程

《Nginx添加内置模块过程》文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验... 目录1、查看Nginx已编辑的模块2、Nginx官网查看内置模块3、停止Nginx服务4、Nginx

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详

Python WSGI HTTP服务器Gunicorn使用详解

《PythonWSGIHTTP服务器Gunicorn使用详解》Gunicorn是Python的WSGI服务器,用于部署Flask/Django应用,性能高且稳定,支持多Worker类型与配置,可处... 目录一、什么是 Gunicorn?二、为什么需要Gunicorn?三、安装Gunicorn四、基本使用启