两种高效的事件处理模式

news/2024/7/9 16:20:08 标签: epoll, 设计模式

服务器程序通常需要处理三类事件:I/O 事件、信号及定时事件。随着网络设计模式的兴起,Reactor 和 Proactor 事件处理模式应运而生。同步 I/O 模型通常用于实现 Reactor 模式,异步 I/O 模型则用于实现 Rroactor 模式。

一、 Reactor 模式

  Reactor 模式要求主线程(I/O 处理单元) 只负责监听文件描述符上是否有事件发生,有的话就立即将该事件通知工作线程(逻辑单元)。除此之外,主线程不做任何其他实质性的工作。读写数据,接受新的连接,以及处理客户请求均在工作线程中完成。
  使用同步 I/O 模型(以 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 模型
  工作线程从请求队列中取出事件后,将根据事件类型来决定如何处理它:对于可读事件,执行读数据和处理请求的操作;对于可写事件,执行写数据的操作。因此,Reactor 模式中没必要区分所谓的 “读工作线程” 和 “写工作线程”。

二、 Proactor 模式

  与 Reactor 模式不同,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 模型

  连接 socket 上的读写事件是通过 aio_read/aio_write 向内核注册的,因此内核将通过信号来向应用程序报告连接 socket 上的读写事件。所以,主线程中的 epoll_wait 调用仅能用来检测监听 socket 上的连接请求事件,而不能用来检测 socket 上的读写事件。


http://www.niftyadmin.cn/n/839814.html

相关文章

本地怎么访问服务器文件,云服务器如何连接本地文件

云服务器如何连接本地文件 内容精选换一换将文件上传至Windows云服务器一般会采用MSTSC远程桌面连接的方式。本节为您介绍本地Windows计算机通过远程桌面连接,上传文件至Windows云服务器的操作方法。Windows云服务器可以访问公网。在本地Windows计算机上&#xff0c…

tinker热修复——资源补丁加载过程

通过上一篇文章《tinker热修复——dex补丁加载过程》,基本上我们已经熟悉了tinker加载dex的过程,tinker除了能够新增类,还可以新增资源和so库等,那么tinker是如何做到热更资源的呢?资源补丁的加载过程又是怎么样的呢&a…

JUnit不能使用Scanner

JUnit不能使用Scanner 和 IO 通过idea工具 Help -> Edit Custom VM Options 打开配置文件 修改配置文件 idea64.exe.vmoptions,在最后一行添加 -Deditable.java.test.consoletrue 可以解决Scanner问题 有时候无效 。。 点击 File - > Invalidate Caches 进…

偶数插入排序 c语言,c语言实现选择排序、冒泡排序、插入排序

#include#pragma warning(disable:4996)int xuanze(int a[],int n);void show(int a[], int n);void maobao(int a[], int n);void insert(int a[], int n);int main() {int a[128],n,i;printf("请输入5个数字&#xff1a;");for (i 0;i < 5;i) {scanf("%d&…

各硬件装置在Linux系统下的文件名

首先要注意&#xff1a;在linux系统中所有的装置都会被当成文件处理。 下面表中的中括号应该这样理解&#xff1a;比如&#xff1a; /dev/ad[a-d]指的是/dev/ada,/dev/adb,/dev/adc,/dev/add也就是说[]里面的东西都要出现 表&#xff1a; ------华丽的分界线-------- 装置----…

telnet IP【程序和功能中的telnet服务器和客户端都已经打开,防火墙中23端口也开着,就是进不去,请看里面吧!】

一&#xff1a;先检查windows环境中telnet功能是否已经开启&#xff1a; 发现都已经打开 然后telnet的时候就是报下面的错误&#xff1a; C:\Users\XXXXX>telnet 192.168.1.159 正在连接192.168.1.159...无法打开到主机的连接。 在端口 23: 连接失败 二&#xff1a;检查防…

服务器系统怎么设置从光盘启动,电脑BIOS怎么设置光盘启动 三种类型BIOS设置光驱启动的图文详解教程...

怎么设置电脑BIOS让电脑使用光盘启动呢?如何使用光盘安装电脑系统?BIOS怎么修改为光盘启动?本文将给大家介绍三种常见类型的BIOS的光盘启动设置方法&#xff0c;下面请看具体操作步骤。主板BIOS类型主要有Phoenix、Award、AMI三种&#xff0c;这里主要围绕这三种界面介绍。各…

磁盘装置文件名的分类

实际上SATA/USB装置文件名为&#xff1a;/dev/sd[a-p],而虚拟机的装置文件名为&#xff1a;/dev/vd[a-p]