5.4 服务器编程基本框架和两种高效的事件处理模式

news2024/12/23 9:57:58

5.4 服务器编程基本框架和两种高效的事件处理模式

服务器编程基本框架

虽然服务器种类繁多,但其基本框架都一样,不同之处在于逻辑处理(比如开发Web服务器项目,浏览器客户端向服务端发送http请求,服务器对请求报文进行解析,根据具体请求信息,将资源找到并组装响应报文,将响应报文发送给客户端,客户端解析出响应)。
在这里插入图片描述
在这里插入图片描述
I/O处理单元是服务器管理客户连接的模块。它通常要完成以下工作:等待并接受新的客户连接,接收客户数据,将服务器响应数据返回给客户端。但是数据的收发不一定在I/O处理单元中执行,也可能在逻辑单元中执行,具体在何处执行取决于事件处理模式。

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

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

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

两种高效的事件处理模式

服务器程序通常需要处理三类事件:I/O事件、信号及定时事件。有两种高效1的事件处理模式:Reactor和Proactor,同步IO模型通常用于实现Reactor模式,异步IO模型通常用于实现Proactor模式。

Reactor模式

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

使用同步IO(以epoll_wait为例)实现的Reactor模式的工作流程是:
1、主线程往epoll内核事件表中注册socket上的读就绪事件
2、主线程调用epoll_wait等待socket上有数据可读
3、当socket上有数据可读时,epoll_wait通知主线程,主线程则将socket可读事件放入请求队列
4、睡眠在请求队列上的某个工作线程被唤醒,它从socket读取数据,并处理客户请求,然后epoll内核事件表中注册该socket上的写就绪事件
5、当主线程调用epoll_wait等待socket可写
6、当socket可写时,epoll_wait通知主线程,主线程将socket可写事件放入请求队列
7、睡眠在请求队列上的某个工作线程被唤醒,它往socket上写入服务器处理客户请求的结果

Reactor模式的工作流程:
在这里插入图片描述

Proactor模式

Proactor模式将所有IO操作都交给主线程和内核来处理(进行读、写),工作线程仅仅负责业务逻辑。使用异步IO模型(以aio_read和aio_write为例)实现Proactor模式的工作流程是:
1、主线程调用aio_read函数向内核注册socket上的读完成事件,并告诉内核用户读缓冲区的位置,以及读操作完成时如何通知应用程序(这里以信号为例)
2、主线程继续处理其他逻辑
3、当socket上的数据被读入用户缓冲区后,内核向应用程序发送一个信号,以通知应用程序数据已经可用
4、应用程序预先定义好的信号处理函数选择一个工作线程来处理客户请求。工作线程处理完客户请求后,调用aio_write函数向内核注册socket上的写完成事件,并告诉内核用户写缓冲区的位置,以及写操作完成时如何通知应用程序。
5、主线程继续处理其他逻辑
6、当用户缓冲区的数据被写入socket之后,内核将向应用程序发送一个信号,以通知应用程序数据已经发送完毕
7、应用程序预先定义好的信号处理函数选择一个工作线程来善后处理,比如决定是否关闭socket

Proactor模式的工作模式:
在这里插入图片描述

模拟Proactor模式

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

使用同步IO模型(以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上写入服务器处理客户请求的结果。

同步IO模拟Proactor模式的工作流程:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/713776.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高压线路零序电流方向保护程序逻辑原理(三)

四、零序保护故障处理程序原理 零序保护逻辑程序可分为三个模块:快速动作部分、全相循环和非全相循环模块。这是根据零序保护的特点而设计的。任何一种高压线路保护都要求快速处理I段范围内的严重故障,所以零序保护与距离保护一样配有快速动作部分程序模…

分不清楚蝴蝶的种类,让AI来告诉你,基于YOLOv5开发构建轻量级蝴蝶细粒度目标检测识别系统

小时候有时间就很喜欢趁着下课放学的时间去抓蝴蝶玩,五彩多样的蝴蝶让人应接不暇,现在早就过了那个天真玩耍的年纪了,如今看到蝴蝶的第一反应就是这是什么蝴蝶,没有专业的知识支撑很难识别出来具体的种类,本文的主要目…

电脑bios使用的uefi启动,系统盘使用的mbr格式,为什么安装完系统无法进入?

概要 在电脑的安装系统过程中,我们会遇到一些问题,比如说使用UEFI启动但是磁盘分区使用MBR格式,导致系统安装完成之后无法引导。这是因为UEFI启动只支持GPT格式的磁盘分区。 在本文中,我们将探讨如何将磁盘转换成GPT格式&#xf…

一种新的程序在线升级的实现(学习)

介绍一种新的程序在线升级方法,以及程序在线升级在嵌入式系统中的应用和实现。设计将从系统原理和实现介绍该程序在线升级方法。利用串口作为通讯方式,自定义通讯协议。 上位机将升级文件传给下位机,下位机将数据解析后存储在内部Flash中。解…

用矩阵处理3D变换

Rotation 也可以把三个旋转矩阵合并为一个综合旋转矩阵: 平移和旋转结合 有时我们想要将平移和旋转结合起来,这样我们就可以在一次操作中同时进行两者,但是我们不能用3x3矩阵来做3D平移,只能用4x4矩阵来做,如下所定义&#xff1a…

尚硅谷Docker实战教程-笔记07【Docker常规安装简介】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址:尚硅谷Docker实战教程(docker教程天花板)_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【理念简介、官网介绍、平台入门图解、平台架构图解】尚硅谷Docker实战教程-笔…

嵌入式基础知识-总线带宽

带宽,最容易想到的是上网用的网络带宽,在嵌入式软件开发中,也会用到带宽,这个带宽的含义就不一样了,区别是什么?本篇就来介绍一下,并通过一些例子来进行带宽的计算。 先来简单看下不同领域的带…

交叉熵和softmax

交叉熵cross-entropy loss 最大化似然函数,最小化负的似然对数函数 最终的交叉熵损失函数,最小化该loss: nn.BCELoss def criterion(yhat, y):out -1 * torch.mean(y*torch.log(yhat) (1-y) * torch.log(1-yhat))return outsoftmax

51单片机一氧化碳烟雾报警器mq2MQ7ADC0832采集

实践制作DIY- GC0152--- 一氧化碳烟雾报警器 基于51单片机设计------- 一氧化碳烟雾报警器 二、功能介绍: STC89C52单片机lcd1602adc0832mq2烟雾传感器mq7烟雾传感器蜂鸣器2个按键设定烟雾报警阈值 2个按键设定一氧化碳报警阈值 1.通过ADC0832采集MQ2烟雾输出的电…

嵌入式系统中STM32时钟系统详解

1. STM32的时钟源主要有: 内部时钟 外部时钟 锁相环倍频输出时钟 1.1 详细介绍 HSI(内部高速时钟) 它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入 HSE(外部高速时钟) 接入晶振范围是4-16MHZ&a…

数据结构--线性表(顺序表、单链表、双链表、循环链表、静态链表)

前言 学习所记录,如果能对你有帮助,那就泰裤辣。 目录 1.线性表概念 定义 基本操作 2.顺序表 定义 顺序表的实现--静态分配 动态分配 顺序表的特点 顺序表的插入和删除 顺序表的查找 按位查找 按值查找 3.单链表 定义 单链表的初始化 不带…

112.(cesium篇)cesium地球自转+文字上下滚动

地图之家总目录(订阅之前必须详细了解该博客) 地图之家:cesium+leaflet+echart+地图数据+地图工具等相关内容的介绍 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 112.(cesium篇)cesium地球自转+文字上下滚动 下面献上完整代码…

Kubernetes(k8s)集群搭建,完整无坑,不需要科学上网~

文章目录 写在前面一、准备三个centos7虚拟机1、创建Vagrantfile2、启动三台虚拟机3、配置centos7支持ssh登录(所有机器)4、修改 linux 的 yum 源(所有机器)5、更新并安装依赖(所有机器)6、安装docker&…

SPI硬件实现-GD32

SPI硬件实现-GD32 #include "w25qxx_spi.h"void w25qxx_init(void){// 使能外设时钟w25qxx_rcu_init();// IO口进行配置,使之复用为SPI0, PA4\PA5\PA6\PA7,NSS\SCK\MISO\MOSIw25qxx_io_init();// SPI0初始化w25qxx_spi_init();spi_enable(SPI0); }// 使能外设时钟…

HTTP/HTTPS 简介||HTTP 消息结构

HTTP/HTTPS 简介 HTTP 协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网( WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 HTTP 是一个基于 TCP/IP 通信协议来传递数据&a…

〖动态规划60题〗泰波纳契数列模型

文章目录 1.第N个泰波那契数(简单)解题流程1. 状态表示2. 状态转移方程3. 初始化dp表4. 填表顺序5. 返回值 代码编写 2.三步问题解题流程1. 状态表示2. 状态转移方程3. 初始化dp表4. 填表顺序5. 返回值 代码编写 3.使用最小花费爬楼梯解题流程1. 状态表示…

Redis高可用——主从复制

redis的主从复制 一、Redis 主从复制1.主从复制的作用:2.主从复制流程: 二、搭建Redis 主从复制1.安装 Redis①.环境准备②.修改内核参数③.安装redis④.创建redis工作目录⑤.环境变量⑥.定义systemd服务管理脚本 2.修改 Redis 配置文件(Mast…

阅读源码技巧

目录 搭建 Demo方法论之关注调用栈方法论之死盯日志方法论之查看被调用的地方探索答案作业是的,正如标题描述的这样,我试图通过这篇文章,教会你如何阅读源码。 事情大概是这样的,前段时间,我收到了一个读者发来的类似于这样的示例代码: 他说他知道这三个案例的回滚情况是…

详解TCP

目录 1.TCP概论 1.1.什么是TCP 1.2.TCP连接的建立过程 1.3.TCP的传输过程 1.4.TCP连接的释放过程 2.JAVA中的TCP 3.TCP带来的一些性能问题 1.TCP概论 1.1.什么是TCP 为了保证所有设备能相互通信,从而建立了一张互联互通的计算机网络,在这张大网…

使用java.lang.Record类删除样板代码

样板是一个源自钢铁制造业的术语,其中形成模具以铸造类似的物体。在编程世界中,样板代码是代码的一部分,项目里面使用的地方很多,但是通常创建完成之后就很少或者就不会更改了。在Java中,不可变的数据载体类用于与数据…