重写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实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

CentOS 7部署主域名服务器 DNS的方法

《CentOS7部署主域名服务器DNS的方法》文章详细介绍了在CentOS7上部署主域名服务器DNS的步骤,包括安装BIND服务、配置DNS服务、添加域名区域、创建区域文件、配置反向解析、检查配置... 目录1. 安装 BIND 服务和工具2.  配置 BIND 服务3 . 添加你的域名区域配置4.创建区域

Windows Server服务器上配置FileZilla后,FTP连接不上?

《WindowsServer服务器上配置FileZilla后,FTP连接不上?》WindowsServer服务器上配置FileZilla后,FTP连接错误和操作超时的问题,应该如何解决?首先,通过... 目录在Windohttp://www.chinasem.cnws防火墙开启的情况下,遇到的错误如下:无法与

python中time模块的常用方法及应用详解

《python中time模块的常用方法及应用详解》在Python开发中,时间处理是绕不开的刚需场景,从性能计时到定时任务,从日志记录到数据同步,时间模块始终是开发者最得力的工具之一,本文将通过真实案例... 目录一、时间基石:time.time()典型场景:程序性能分析进阶技巧:结合上下文管理器实现自动计时

Windows server服务器使用blat命令行发送邮件

《Windowsserver服务器使用blat命令行发送邮件》在linux平台的命令行下可以使用mail命令来发送邮件,windows平台没有内置的命令,但可以使用开源的blat,其官方主页为ht... 目录下载blatBAT命令行示例备注总结在linux平台的命令行下可以使用mail命令来发送邮件,Win

Ubuntu 22.04 服务器安装部署(nginx+postgresql)

《Ubuntu22.04服务器安装部署(nginx+postgresql)》Ubuntu22.04LTS是迄今为止最好的Ubuntu版本之一,很多linux的应用服务器都是选择的这个版本... 目录是什么让 Ubuntu 22.04 LTS 变得安全?更新了安全包linux 内核改进一、部署环境二、安装系统

nginx配置多域名共用服务器80端口

《nginx配置多域名共用服务器80端口》本文主要介绍了配置Nginx.conf文件,使得同一台服务器上的服务程序能够根据域名分发到相应的端口进行处理,从而实现用户通过abc.com或xyz.com直... 多个域名,比如两个域名,这两个域名其实共用一台服务器(意味着域名解析到同一个IP),一个域名为abc

pycharm远程连接服务器运行pytorch的过程详解

《pycharm远程连接服务器运行pytorch的过程详解》:本文主要介绍在Linux环境下使用Anaconda管理不同版本的Python环境,并通过PyCharm远程连接服务器来运行PyTorc... 目录linux部署pytorch背景介绍Anaconda安装Linux安装pytorch虚拟环境安装cu