Linux搭建Web服务器(三)——服务器编程基本框架以及事件处理模式

2023-05-16

目录

0x01 服务器编程基本框架

0x02 两种高效的事件处理模式

Reactor 模式

Proactor 模式

模拟Proactor 模式


0x01 服务器编程基本框架

虽然服务器程序的种类繁多,但是其基本框架都是一样的,不同之处是在于处理逻辑。对于我们在这个服务器的搭建可以分为解析-读取-响应三个阶段。

 

  • I/O处理单元:处理客户连接,读写网络数据。它通常要完成以下工作:等待并接受新的客户连接,接收客户数据,将服务器响应数据返回给客户端。但是数据的收发不一定在 I/O 处理单元中执行,也可能在逻辑单元中执行,具体在何处执行取决于事件处理模式

  • 逻辑单元:业务进程或线程。通常是进程或线程。它分析并处理客户数据,然后将结果传递给 I/O 处理单元或者直 接发送给客户端(具体使用哪种方式取决于事件处理模式)。服务器通常拥有多个逻辑单元,以实现对多个客户任务的并发处理

  • 网络存储单元:可以是数据库、缓存和文件,但不是必须的。

  • 请求队列:是各单元之间的通信方式的抽象。I/O 处理单元接收到客户请求时,需要以某种方式通知一个 逻辑单元来处理该请求。同样,多个逻辑单元同时访问一个存储单元时,也需要采用某种机制来协调处理竞态条件。请求队列通常被实现为池的一部分。(进程池、线程池)

对于服务器模型,常见的有C/S模型,也就是常见的TCP服务器与客户端的工作流程,适合在资源相对集中的场合,服务器是通信中心,当访问量过大的适合,可能所有的客户都将面对很慢的响应。还有一种P2P模型,这种模型的每台机器既是主机也是服务器,当用户之间传输请求过多时,网络的负载将加重。

对于两种高效的并发模式:并发模式是指I/O处理单元和多个逻辑单元之间协调完成任务的方法。两种并发编程模式:半同步/半异步模式、领跑者/追随者模式。

半同步/半异步模式

  • 同步:程序完全按照代码序列的顺序执行——同步线程

  • 异步:程序的执行需要有系统事件来驱动,如中断、信号等——异步线程

在半同步/半异步模式中,同步线程用于处理客户逻辑,异步线程用于处理I/O事件。异步线程监听到客户请求后,将其封装成请求对象并插入请求队列中。请求队列将通知某个工作在同步模式的工作线程来读取并处理请求对象。

如果结合考虑两种事件处理模式和几种I/O模型,半同步/半异步模式就存在多种变体:

  • 半同步/半反应堆模式:异步线程只有主线程,同步线程为多个工作线程

  • 高效的半同步/半异步模式:主线程只负责监听socket,连接socket由工作线程来管理

领跑者/追随者模式

  • 领导者/追随者模式是多个工作线程轮流获得事件源集合,轮流监听、分发并处理事件。

  • 在任意的时间点,程序都仅有一个领导者进程,它负责监听I/O事件;其他线程则都是追随者,它们休眠在线程池中等待成为新的领导者。

  • 当前的领导者如果检测到I/O事件,首先要从线程池中推选出新的领导者线程,然后处理I/O事件。此时,新的领导者等待新的I/O事件而原来的领导者则处理I/O事件,二者实现了并发。

需要的组件有如下:

  • 句柄集(HandleSet):句柄I/O资源,通常为一个文件描述符;句柄集使用wait_for_event监听I/O事件等

  • 线程集(ThreadSet):所有工作进程的管理者,负责各线程之间的同步,以及新领导者的推选;三种状态:Leader,Processing 和Follower

  • 事件处理器(EventHander)和 (ConcreteEventHandler):包含一个或多个回调函数handle_event

缺点:领导者/追随者模式仅支持一个事件源集合,无法让每个工作线程独立的管理多个客户连接

0x02 两种高效的事件处理模式

服务器程序通常需要处理三类事件:I/O 事件、信号及定时事件。有两种高效的事件处理模式:Reactor 和 Proactor:

  • 同步 I/O 模型通常用于实现 Reactor 模式

  • 异步 I/O 模型通常用于实现 Proactor 模式

其中异步IO的模式可以使用同步IO来进行模拟得出。

Reactor 模式

在这里只考虑线程,在这里要使用多线程进行并发处理,在这里有主线程以及子线程,要求主线程(I/O处理单元)只负责监听文件描述符上是否有事件发生,有的话就立即将该事件通知工作线程(逻辑单元),将 socket 可读可写事件放入请求队列,交给工作线程处理(子线程)。除此之外,主线程不做任何其他实质性的工作。读写数据,接受新的连接,以及处理客户请求均在工作线程中完成。(只负责监听)

主要的工作流程如下:

使用同步 I/O(以 epoll_wait 为例)实现的 Reactor 模式的工作流程是:

  1. 主线程往 epoll 内核事件表中注册 socket 上的读就绪事件。

  2. 主线程调用 epoll_wait 等待 socket 上有数据可读。

  3. 当 socket 上有数据可读时, epoll_wait 通知主线程。主线程则将 socket 可读事件放入请求队列

  1. 睡眠在请求队列上的某个工作线程被唤醒,它从 socket 读取数据,并处理客户请求,然后往 epoll内核事件表中注册该 socket 上的写就绪事件。

  2. 主线程调用 epoll_wait 等待 socket 可写。

  3. 当 socket 可写时,epoll_wait 通知主线程。主线程将 socket 可写事件放入请求队列

  4. 睡眠在请求队列上的某个工作线程被唤醒,它往 socket 上写入服务器处理客户请求的结果。

在这里,主进程只负责监听以及工作交互,子线程负责对事件进行读写。

Proactor 模式

Proactor 模式将所有 I/O 操作都交给主线程和内核来处理(进行读、写),工作线程仅仅负责业务逻辑。使用异步 I/O 模型(以 aio_read 和 aio_write 为例)实现的 Proactor 模式的工作流程是:

 

 

区别在于数据是否在主线程中进行处理,也就是同步与异步的区别,直接得到了数据的读写结果。

  1. 主线程调用 aio_read 函数向内核注册 socket 上的读完成事件,并告诉内核用户读缓冲区的位置,以及读操作完成时如何通知应用程序(这里以信号为例)。

  2. 主线程继续处理其他逻辑。

  3. 当 socket 上的数据被读入用户缓冲区后,内核将向应用程序发送一个信号,以通知应用程序数据已经可用

  4. 应用程序预先定义好的信号处理函数选择一个工作线程来处理客户请求。工作线程处理完客户请求后,调用 aio_write 函数向内核注册 socket 上的写完成事件,并告诉内核用户写缓冲区的位置,以及写操作完成时如何通知应用程序。

  5. 主线程继续处理其他逻辑。

  6. 当用户缓冲区的数据被写入 socket 之后,内核将向应用程序发送一个信号,以通知应用程序数据已经发送完毕。

  7. 应用程序预先定义好的信号处理函数选择一个工作线程来做善后处理,比如决定是否关闭 socket。

模拟Proactor 模式

使用同步 I/O 方式模拟出 Proactor 模式。原理是:主线程执行数据读写操作,读写完成之后,主线程向工作线程通知这一”完成事件“。那么从工作线程的角度来看,它们就直接获得了数据读写的结果,接下来要做的只是对读写的结果进行逻辑处理。

使用同步 I/O 模型(以 epoll_wait为例)模拟出的 Proactor 模式的工作流程如下:

  1. 主线程往 epoll 内核事件表中注册 socket 上的读就绪事件。

  2. 主线程调用 epoll_wait 等待 socket 上有数据可读。

  3. 当 socket 上有数据可读时,epoll_wait 通知主线程。主线程从 socket 循环读取数据,直到没有更多数据可读,然后将读取到的数据封装成一个请求对象并插入请求队列

  4. 睡眠在请求队列上的某个工作线程被唤醒,它获得请求对象并处理客户请求,然后往 epoll 内核事件表中注册 socket 上的写就绪事件。

  5. 主线程调用 epoll_wait 等待 socket 可写。

  6. 当 socket 可写时,epoll_wait 通知主线程。主线程往 socket 上写入服务器处理客户请求的结果。

其Reactor模式与Proactor模式做个简单的区分主要在于如下:

Reactor模式——当事件就绪,通知工作线程。

Proactor模式——当事件就绪,内核完成读写后,通知工作线程。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux搭建Web服务器(三)——服务器编程基本框架以及事件处理模式 的相关文章

随机推荐

  • 数学建模(一)—— 人口增长模型的确定

    一 题目要求二 相关的基础知识2 1 马尔萨斯 Malthus 人口指数增长模型2 2 逻辑斯蒂 Logistic 增长模型2 3 改进的Logistic模型2 4 BP神经网络模型 三 模型的建立与求解3 1 Malthus模型3 2 L
  • 将火狐浏览器视频播放倍速设置为3倍速及其以上

    看视频最快只能两倍速 xff1f 使用火狐浏览器看视频时将视频播放倍速提升到最快16倍速的方法来了 xff01 xff01 xff01 step1 xff1a 打开火狐浏览器页面左上角的应用程序菜单 xff0c 点击扩展和主题 xff1b
  • 折半插入排序算法

    折半插入排序 xff08 Binary Insertion Sort xff09 是对插入排序算法的一种改进 所谓插入排序 xff0c 就是不断的依次将元素插入前面已排好序的序列中 由于前半部分为已排好序的数列 xff0c 这样我们不用按顺
  • VOC2007数据集详细分析

    VOC数据集官网链接 http host robots ox ac uk pascal VOC VOC2007数据集官网链接 http host robots ox ac uk pascal VOC voc2007 index html V
  • Requirement already satisfied解决办法

    遇到的问题 xff1a 当使用电脑中安装的Python 3 7的IDLE去运行某一个python文件时 xff0c 会出现ModuleNotFoundError No module named 39 numpy 39 的报错 xff0c 需
  • 使用Python将DOTA数据集的格式转换成VOC2007数据集的格式

    一 VOC2007数据集二 DOTA数据集三 将DOTA数据集的格式转换成VOC2007数据集的格式 一 VOC2007数据集 VOC2007数据集的文件结构如下图所示 其中 xff0c 文件夹Annotations中存放的是图像的标注信息
  • 设计一个卷积神经网络模型用于遥感图像的场景分类

    遥感图像场景分类是指对遥感图像中场景语义内容标签的映射过程 xff0c 对高分辨率遥感影像的信息提取及内容理解有着重要的意义 主要的场景分类方法可以分为三类 xff1a 第一类是基于底层视觉特征的场景分类方法 xff0c 第二类是基于中层视
  • 使用Python随机生成数据的一些方法

    通过Python Faker生成测试数据通过Python基础语法生成一些随机数利用26个字母和10个数字随机生成5个八位密码生成5个2位小数点的随机数生成5个随机整数数 通过Python Faker生成测试数据 通过Python Faker
  • 源码阅读及理论详解《 Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting 》

    Informer论文 xff1a https arxiv org pdf 2012 07436 pdf Informer源码 xff1a GitHub zhouhaoyi Informer2020 The GitHub repository
  • Python实现排序

    在Python中可以使用提供的sort排序法对list实现排序 Python提供两种内置排序的函数分别是sort 和sorted xff0c 这两种函数用法差别在于sort 会直接修改原始的list进行排序 xff0c sorted 可迭代
  • Python排序进阶版:根据一个列表的顺序对其他列表进行排序

    在Python中如果需要根据列表A对列表B进行排序的问题时有以下2种方法 xff1a 方法1 xff1a 根据列表B中每个元素的下标来获取列表A中对应位置的元素 xff0c 将其作为排序依据即可 a span class token ope
  • 基于MATLAB GUI的系统设计(四)

    接下来学习的是关于图像处理方面的知识 实例一 xff1a 对图像进行灰度处理 直方图均衡化处理 二值处理以及用Canny算子对图像进行边缘检测 第一步 xff1a GUIDE画界面 第二步 xff1a 编辑代码 function varar
  • HashMap的工作原理(图文+例子)详解,绝对简单通俗易懂

    目录 什么是HashMap xff1f HashMap的内部结构 内部结构之数组 内部结构之链表 Put方法与Get方法原理 JDK1 7月JDK1 8中HashMap的区别 什么是HashMap xff1f 基于哈希表的 Map 接口的实
  • vnc序列号

    5D7L8 ZQXSA 2L5D4 4UFB4 PWDLA 8KNFU MZZHE WA449 2SLLH 48Q7A
  • A星(A*、A Star)路径规划算法详解(附MATLAB代码)

    首先看看运行效果 xff0c 分别有三种模式 xff0c 代码运行前需要通过鼠标点击设置起点和终点 第一种模式直接输出最短路径 第二种模式输出最短路径的生成过程 第三种模式输出最短路径的生成过程和详细探索的过程 代码获取 gitee链接 x
  • ubuntu系统支持GIGABYTE X570 I AORUS PRO WIFI主板温度及风扇转速检测

    原文链接 xff1a How to fix bugs in Ubuntu 20 04 LTS after installation 43 all necessary programs ITCooky Recipes Not getting
  • 计算机启动过程(windows XP 系统)

    计算机启动过程 xff08 windows XP 系统 xff09 共五步 1 预引导 Pre Boot 阶段 xff1b 2 引导阶段 xff1b 3 加载内核阶段 xff1b 4 初始化内核阶段 xff1b 5 登陆 第一个阶段 首先
  • 2006年6月21日

    最近住了一段时间医院 xff0c 在那里除了休息就是休息 xff0c 回来都一周了 xff0c 我都没有适应了学校的生活 xff0c 一天除了睡觉就是看世界杯 哈哈 xff0c 得要有个好心态 看一点东西就算一点 xff0c 写出来 xff
  • 2006 年6月23日

    我为网上下载的一个TDI的源代码写了一个source文件 xff0c 可是编译时却出现了如下问题 can 39 t open include file 34 netpnp h 34 以及 can 39 t open input file 3
  • Linux搭建Web服务器(三)——服务器编程基本框架以及事件处理模式

    目录 0x01 服务器编程基本框架 0x02 两种高效的事件处理模式 Reactor 模式 Proactor 模式 模拟Proactor 模式 0x01 服务器编程基本框架 虽然服务器程序的种类繁多 xff0c 但是其基本框架都是一样的 x