Libevent源码剖析之reactor
1 简介
reactor 是一种事件驱动的并发处理模式,常用于网络服务器和事件循环系统中。它主要的功能是通过单线程或者多线程处理I/O操作,避免阻塞,并且能够高效处理大量并发的事件。
one loop per thread or process,以下摘自 reactor 原文:
The reactor software design pattern is an event handling strategy that can respond to many potential service requests concurrently. The pattern's key component is an event loop, running in a single thread or process, which demultiplexes incoming requests and dispatches them to the correct request handler.[1]
By relying on event-based mechanisms rather than blocking I/O or multi-threading, a reactor can handle many concurrent I/O bound requests with minimal delay.[2] A reactor also allows for easily modifying or expanding specific request handler routines, though the pattern does have some drawbacks and limitations.[1]
With its balance of simplicity and scalability, the reactor has become a central architectural element in several server applications and software frameworks for networking. Derivations such as the multireactor and proactor also exist for special cases where even greater throughput, performance, or request complexity are necessary.[1][2][3][4]
在此列出多路复用相关文章:
Libevent源码剖析之iocp-CSDN博客
Libevent源码剖析之reactor-CSDN博客
Libevent源码剖析之epoll-CSDN博客
Libevent源码剖析之poll-CSDN博客
Libevent源码剖析之select-CSDN博客
1.1 工作组件
事件源:系统中会有多个事件源,例如网络套接字、文件描述符、定时器等,触发各种事件,如读、写、超时等。
事件分离器 (Demultiplexer):事件分离器(通常是系统调用,如select(), poll(), 或epoll())负责监控这些事件源,并将发生事件的事件源标记出来。
事件分派器 (Dispatcher):Reactor设计中的核心部分,事件分派器接收到事件分离器传来的事件后,将其分发给相应的处理器(Event Handler)处理。每个事件对应一个预定义的事件处理函数。
事件处理器 (Event Handler):事件处理器包含事件处理的逻辑。当事件分派器传递某个事件时,事件处理器负责处理该事件,例如处理网络连接请求,或者读取某个套接字中的数据。
1.2 工作流程
- 等待事件发生:reactor首先通过系统调用(如select()或epoll())等待某些I/O事件发生。
- 事件分离:当某个I/O事件发生时,事件分离器(select()或epoll())返回一组已经就绪的事件。
- 事件处理:事件分派器检查哪些事件已经准备好,并将这些事件交由对应的事件处理器进行处理。
- 继续监听:事件处理结束后,reactor重新回到等待事件的状态,重复此过程。
1.3 单线程 vs 多线程
- 单线程 reactor:适合处理简单的并发情况,整个流程都是在一个线程中进行,因此不需要考虑线程同步问题。然而,当处理时间较长的操作时,可能会阻塞其他事件的处理,开源软件比如redis缓存数据库。
- 多线程 reactor:将I/O事件和实际事件处理分开。reactor在单线程中监听和分派事件,而将事件处理分配给工作线程(Thread Pool)。这样可以避免阻塞,提高并发处理能力,开源软件如memcached缓存数据库。
1.4 reactor 和 proactor
- reactor 是同步非阻塞模型,事件循环等待事件发生,当某个事件准备好后,交给处理器进行处理。
- proactor 则是异步模型,事件发生时由内核完成操作(如I/O操作),然后通知应用程序进行进一步处理。
2 原理
2.1 组件图
reactor相关组件图如下:
2.2 序列图
各组件工作序列图:
3 reactor
3.1 classic service design
解释说明:
- 此为同步阻塞模式;
- 逐个处理client请求,当1个client连接成功后,read => decode => compute => encode => send,如此流程处理完毕,方可处理下一个client请求;
- 以client为并发粒度,粒度大,并发响应延迟高,不适合高并发场景,适用于mysql这种应用场景;
- handler可以是一个线程或进程;
3.2 single reactor per thread
解释说明:
- 1个线程1个reactor,1个acceptor,所有client的IO事件收集&分发&处理,均在此线程处理;
- 此线程持有1个acceptor,专门用来并发处理client的connect请求;
- 所有的IO操作和计算任务,均在此reactor线程处理;
- 并发粒度为event,而非client,并发粒度低,并且能很好的解决数据乱序问题,但不能发挥多CPU核心优势,适用于redis这种内存数据库;
- 若设计为multiple single reactor per thread,如此便可解决此模式的缺陷,既能发挥多CPU核心优势,又能适用于IO密集型,非常灵活,但若是多进程下需解决accept惊群问题,如nginx;
3.3 single reactor + work thread poll
-
解释说明:
- 此模式在single reactor per thread基础之上,将IO操作和event业务逻辑处理分离开来,由reactor线程充当acceptor和所有IO操作职责,所有计算任务由thread poll来处理;
- 当1个client请求过来,reactor的acceptor accept客户端的connect请求,然后read数据完毕,将fd和业务逻辑处理handler封装起来,投递到queued tasks中,从thread poll中分配1个线程来处理,待处理完毕,再回到reactor线程发送给client,如此循环;
- reactor线程和thread poll通过队列来通信,前者处理IO操作,后者处理业务逻辑;
- 缺点:acceptor和所有IO操作,均由reactor线程处理,瓶颈在此;
- 优点:将IO操作交由reactor线程,业务逻辑交由thread poll,可充分发挥多CPU核心优势,也可很好的解决数据乱序问题,适用于高并发场景;
- 可通过设计为multiple single reactor + work thread poll来解决以上问题;
3.4 multiple reactor + thread poll

解释说明:
- 与single reactor + work thread poll不同之处在于,此模式将reactor线程根据职责,一分为二,分离出mainReactor线程和subReactor线程,前者专门负责并发处理client的connect请求,后者则负责处理所有IO操作;
- 其他均与single reactor + work thread poll模式一致,不再赘述;
4 参考文献
4.1 reactor wiki
https://en.wikipedia.org/wiki/Reactor_pattern#Structure
4.2 reactor pattern
Scalable IO in Java
相关文章:
Libevent源码剖析之reactor
1 简介 reactor 是一种事件驱动的并发处理模式,常用于网络服务器和事件循环系统中。它主要的功能是通过单线程或者多线程处理I/O操作,避免阻塞,并且能够高效处理大量并发的事件。 one loop per thread or process,以下摘自 reacto…...
分享一套SpringBoot+Vue民宿(预约)系统
大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue民宿(预约)系统,分享下嘿嘿。 项目介绍 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,…...
Linux——应用软件的生命周期
功能开发测试: 功能性测试 对应开发框架的测试用例代码的漏洞扫描 Web服务器版本应用开发语言的依赖关系和版本信息是否会造成类似内存泄露等影响系统性能的问题压力测试应用的部署 获取应用代码以及应用静态文件的代码包将安装包中的文件按照服务器配置的架构&…...
【Linux】exec系列函数详细介绍
首先,exec 是 execute (意为:执行) 的缩写。 exec系列函数 各个“后缀”的意思: l 为 list 可变参数列表、v 为 vector、p 为 PATH、e 为环境变量数组 envp execl:l 为 list 可变参数列表 原型:int execl(const char *path, cons…...
ARINC 429总线协议
一、概述 ARINC 是美国航空无线电公司英文字头的缩写, 该公司1977年7月21日出版了“ARINC 429规范”一书,429规范就是飞机电子系统之间数字式数据传输的标准格式,在飞机上使用429总线的电子设备均应遵守这个规范,这样才能保证电子…...
Qt解决槽函数中发送的信号的参数会变化带来的错误
connect(item, &MusicItemWidget::playRequest, this, [this] { emit playMusic(QUrl(this->m_mediaPath); ); 如上图,this->m_mediaPath是个成员变量,但自己的初衷是发送一个最开始捕获的值,那么可以使用下面的方法…...
C C++ 如何编写库级接口
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
安装TDengine数据库3.3版本和TDengine数据库可视化管理工具
安装TDengine数据库3.3版本和TDengine数据库可视化管理工具 一、下载安装包二、解压安装包三、部署四、启动服务五、进入数据库六、创建数据库、表和往表中插入数据七、测试 TDengine 性能八、使用数据库九、查询数据十、TDengine数据库可视化界面 一、下载安装包 TDengine-cl…...
详解CAS
一、CAS是什么? CAS是Java中Unsafe类里面的一个方法,是Compare and Swap的缩写,中文翻译成比较并交换,主要功能是能够去保证在多线程的环境下对于共享变量修改的一个原子性,实现并发算法时常用到的一种技术。它包含三…...
《环境感知方案:探索未来智能世界的关键技术》
《环境感知方案:探索未来智能世界的关键技术》 一、环境感知方案的研究现状(一)机器人领域的环境感知(二)农业领域的环境感知(三)智能网联汽车领域的环境感知 二、先进的环境感知技术࿰…...
Android 编译时出现Android resource linking failed.without required default value.
错误信息如下: Execution failed for task :app:processDebugResources. > A failure occurred while executing com.android.build.gradle.internal.res.LinkApplicationAndroidResourcesTask$TaskAction> Android resource linking failedwarn: removing r…...
golang ws升级为wss
首先需要一份openssl证书 1.安装openssl windows安装openssl 的下载地址在 https://slproweb.com/products/Win32OpenSSL.html 无脑点安装就行,记得最后安装完成的页面取消勾选 安装完成后记得配置环境变量 2.生成证书 openssl req -x509 -days 36500 -nodes …...
FFMPEG录屏(17)--- 使用 DwmRegisterThumbnail 捕获指定窗口图像数据
使用 DwmRegisterThumbnail 捕获指定窗口图像数据 在 Windows 平台上,捕获指定窗口的图像数据可以通过多种方法实现,其中一种高效的方法是使用 [DwmRegisterThumbnail] 本文将介绍如何使用 [DwmRegisterThumbnail] 捕获窗口图像数据,并提供一…...
点亮一个LED(51)
目录 1.LED介绍 2.硬件电路 3.程序设计 3.1.点亮一颗LED 3.2.LED闪烁 3.3.LED流水灯实现 1.LED介绍 发光二极管也具有二极管普遍的特性单向导电性,有阳极和阴极之分 ,上图左侧式插件式LED ,长的引脚是阳极;左侧是贴片式的带…...
Flink窗口分配器WindowAssigner
前言 Flink 数据流经过 keyBy 分组后,下一步就是 WindowAssigner。 WindowAssigner 定义了 stream 中的元素如何被分发到各个窗口,元素可以被分发到一个或多个窗口中,Flink 内置了常用的窗口分配器,包括:tumbling wi…...
【Tinymce】富文本编辑器在vue项目中的使用;引入付费格式刷,上传视频、图片
引言 富文本编辑器有很多,对比了一下,还是决定用tinymce(号称宇宙最强),基础的插件确实好用,但是一些更好用的插件,比如格式刷等都是高级版(付费),当然也有人…...
Java实现简单的5阶m序列密钥生成
选择5阶本原多项式:x^5 x^2 1,初始值为{1,0,0,1,1},易得,递推公式为:ak ak-5 ⊕ ak-2 ,其中k≥5。于是可以写出下面这段代码: class BitsEncode {public static void main(String[] args) {//初始化数组…...
013_django基于大数据的高血压人群分析系统2024_dcb7986h_055
目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍:CodeMentor毕业设计领航者、全网关注者30W群落,InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者,博客领航之星、开发者头条/腾讯云/AW…...
OpenCV高级图形用户界面(21)暂停程序执行并等待用户按键输入函数waitKey()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 等待按键 该函数 waitKey 在 delay≤0 时无限等待按键事件,或者在 delay 为正数时等待 delay 毫秒。由于操作系统在切换线程时有最小…...
其他css的用途
1.animation-fill-mode: backwards; //避免了在动画开始前元素的突然显现,动画必要。 2.用rem响应式字体大小,可以在html样式定义font-size?(例10px,62.5%(100%是16px))。然后样式就可以用rem代替px。 3.color: transparent;: 这行代码将文…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...

