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;: 这行代码将文…...

json路径 [‘a‘].b.c[0].d[‘1‘].f,具体代表什么意思
JSON路径是一种用于从JSON对象中提取数据的表达方式。你给出的路径 [a].b.c.d[1].f 代表了如何逐层访问JSON对象中的数据。让我们逐步解析这个路径: [a]: 表示访问JSON对象的根元素中键为 a 的值。使用方括号 [] 通常意味着这个键是一个字符串&#…...

等保测评:如何进行有效的安全合规性审查
等保测评(信息安全等级保护测评)是一项至关重要的安全合规性审查工作,旨在帮助组织保障信息系统的安全性、合规性,有效应对安全风险,提升整体安全防护水平。下面将从等保测评的流程、意义、应用场景,以及实…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发二 : 18.04ubuntu安装,linux 下build ffmpeg 4.3 源码 并测试
测试环境 ubuntu 18.04 64 位,安装vmware and ubuntu 安装后调整 分辨率: 让windows 可以和 linux 互相复制黏贴 sudo apt-get autoremove open-vm-tools sudo apt-get update sudo apt-get install open-vm-tools-desktop 一直Y reboot 依赖安装 sud…...

将两张图片的不同标记出来
差异过于细微,阈值设置不当:您的差异可能是颜色或位置的微小变化,当前的阈值和处理方式可能不足以检测到这些细微差异。 图像配准不够精确:由于两张图片内容高度相似,特征点匹配可能存在误差,导致图像对齐…...

HarmonyOS开发(State模型)
一、State模型概述 FA(Feature Ability)模型:从API 7开始支持的模型,已经不再主推。 Stage模型:从API 9开始新增的模型,是目前主推且会长期演进的模型。在该模型中,由于提供了AbilityStage、Wi…...

在 WPF 中使用 OpenTK:从入门到进阶
一、引言 WPF(Windows Presentation Foundation)是微软推出的用于创建丰富的桌面应用程序用户界面的框架。OpenTK 则为我们提供了强大的图形处理能力,包括 3D 图形渲染、数学计算等功能。将两者结合起来,可以在 WPF 应用程序中实…...

【最新华为OD机试E卷-支持在线评测】水仙花数(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…...

C# WinForm 用名字name字符串查找子控件
工作上遇到界面控件太多,需要对一些控件批量处理。虽然可以用代码批量控制,但要么是建立数组集合把所有要处理的控件放进去循环处理,要么是一个一个列出来修改属性。 但我大多数要求改的控件命名上是有规律的,所有只需要循环拼接字…...

Ubuntu下安装并初始化Git同时添加SSH密钥
在 Ubuntu 上可以使用以下命令安装git: sudo apt-get update sudo apt-get install git 在 Ubuntu 下安装好 Git 之后,接下来可以进行一些基本的配置和操作,以便更好地使用 Git。 1. 配置 Git 用户信息 在使用 Git 进行版本控制前&#x…...

好用的AI工具:探索智能生活的无限可能
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《热点时事》 期待您的关注 目录 引言 一:常用AI工具 1. 语音助手(如Siri、小爱同学) 2. 智…...