Reactor反应堆模式

一、什么是Reactor模式

Reactor 模式是一种事件驱动的编程模式,用于高效地处理并发 I/O 操作,它通过一个或多个事件循环(Event Loop)来监听和处理各种事件,例如网络请求、定时器事件等,从而实现高效的并发处理,而无需为每个连接创建一个线程或者进程。

二、单Reactor模式

单 Reactor,顾名思义,整个程序只有一个 Reactor(一套 Event Loop 事件循环)。 这唯一的事件循环,会同时做两件大事:第一件是监听端口,等待新客户端连接,调用 accept 拿到新连接;第二件是负责所有已建立连接上的可读、可写事件,触发读写回调处理业务。所有连接的全部 I/O 事件,都挤在同一个事件循环里串行执行。

Redis 就是单 Reactor 单进程模型最经典的案例,利用非阻塞 I/O 和内存数据的高效处理,在保证性能的同时极大简化了设计。

单 Reactor 的优势在于其架构简单,代码容易维护,不存在多线程之间锁竞争的开销。而单 Reactor 的缺点是它的所有任务是串行执行。一旦某个业务回调执行耗时久,就会阻塞整个事件循环,其他所有连接的事件都会被卡住,无法及时处理;同时只能利用单个 CPU 核心,无法充分发挥多核机器的算力。

三、多Reactor模式

多Reactor 会创建多个独立的 Reactor 事件循环 ,一般拆分为主 Reactor(main reactor)和多个从 Reactor(sub reactor),也就是 One Thread One Loop,一个线程绑定一个 Reactor,每个 Reactor 都拥有独立的 epoll 和事件循环,相互之间不干扰。

主 Reactor 职责很单一:只负责监听端口,只处理 accept 事件,专门接收客户端发起的新连接。当主 Reactor 获取到新 socket 连接之后,不会自己处理这个连接后续的读写,而是把这个 socket fd 分发到其中一个空闲的从 Reactor。 从 Reactor 拿到这个 fd 之后,会将 fd 注册进自己的 epoll,之后这条连接上所有的读、写事件,全部都由这个从 Reactor 独立负责,全程不会再交给其他 Reactor。不同从 Reactor 各自处理自己名下的连接,多个事件循环跑在不同 CPU 核心上,充分利用多核。

我们不推荐 reactor 加上线程池的模式,因为多线程场景下,各个线程完成任务返回的顺序,有可能和任务传入的顺序不一致,会出现时序错乱的问题。所以在工程实践当中,一般采用 One Thread One Loop 的模式,也就是一个线程对应一个独立的事件循环,每一个线程各自处理自己的任务,互不干扰。

**One Thread One Loop(OTOL)**是一种设计模式,通常用于描述基于事件驱动编程的架构,尤其常用在异步 I/O 框架。这种模式规定每个线程运行一套独立的事件循环 Event Loop,以此实现高效并发处理。 事件循环(Event Loop)是异步编程的核心,负责监听事件,包括 I/O 操作、定时器事件,并且触发对应的回调函数。它本身是单线程执行模型,依靠 epoll、select、poll 这类 IO 多路复用技术,高效管理大量文件描述符。

主 Reactor 分发新连接给从 Reactor 时,需要线程间通信传递 fd。普通多线程模式下,多个线程共享文件描述符表,会产生资源竞争问题。这里不能用条件变量加互斥锁的方式搭建任务分发队列。原因是 epoll_wait 本身就是让线程阻塞等待事件,当 I/O 事件就绪的时候,如果线程还卡在条件变量的等待逻辑里,就没办法及时唤醒处理 I/O。所以工程上会采用管道来完成线程间传递 fd,往管道写入 fd,就等价于实现条件变量加互斥锁的消息队列。

如果不想使用管道的方式,还可以使用 eventfd 实现事件驱动,完成线程间的通知。

Eventfd 工作模式:

普通模式:不设置 EFD_SEMAPHORE 标志,读取 eventfd 的时候,内部计数器会直接清空。

设置 EFD_SEMAPHORE:信号量模式,每次读取只会让计数器减 1,不会一次性清零。

相关推荐
qq_37180211几秒前
Ubuntu Linux中安装WorkBuddy
linux·运维·服务器·ubuntu
无足鸟ICT8 分钟前
【RHCA+】iptraf-ng(网络监控分析)
linux·网络
独隅21 分钟前
WebStorm 在 Linux 环境下的实战安装与高效开发指南
linux·ide·webstorm
坤坤子吖2 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
阡陌数智2 小时前
Claude API新版本重大变更与安全升级指南
java·linux·安全
奶茶树3 小时前
【Linux】环境开发工具(vim,gcc,g++,Makefile)
linux·运维·vim
xiaoye-duck3 小时前
《C++ 项目:手写大模型接入 SDK》LLMManager架构设计与实现
开发语言·网络·c++·语言模型
say_fall4 小时前
【AI大模型】MCP 模型上下文协议:客户端-服务器架构、JSON-RPC 消息与能力协商、工具发现与调用链路、与函数调用的分工
服务器·人工智能·架构
andxe4 小时前
工业级 PoE 交换机选型指南:破解边缘部署四大核心难题
运维·网络·安全·光通信·交换机
木子欢儿6 小时前
国内 macOS/Linux 安装 rust
linux·运维·服务器·macos·rust