当前位置: 首页 > java >正文

快速入门Socket编程——封装一套便捷的Socket编程——Reactor

快速入门Socket编程——封装一套便捷的Socket编程——Reactor 设计模式

​ 我们下面来聊一聊基于Epoll的Reactor 设计模式,这里构成了笔者设计的核心思路。

​ 我们可以直到Reactor 模式是一种典型的 事件驱动(Event-Driven)设计模式。我们一次性的监听多个 I/O 句柄的事件(可读、可写、异常)。这实际上是一种I/O 多路复用机制

I/O 多路复用机制(如 selectpollepoll):一个进程或线程可以同时监视多个文件描述符(File Descriptor, FD),并在其中任何一个文件描述符就绪(ready for I/O)时,得到通知并进行相应的操作,而无需阻塞在单个 I/O 操作上。

​ 当我们监听到了事件的来源的时候,我们就会Reactor 分发(dispatch)事件到对应的 Handler(事件处理器)

一句话理解:

Reactor 模式中,应用程序主动从内核查询事件,然后调用回调函数处理


Reactor 模式的角色

  1. Reactor(事件分发器)
    • 负责监听事件并分发给对应的 Handler。
  2. Handle(句柄)
    • I/O 资源,如 socket_fd
  3. Event Handler(事件处理器)
    • 负责响应某个 I/O 事件的回调函数

Reactor 的典型工作流程

​ 在笔者之后全面的介绍代码的时候,会详细的说明,这里给出一个片段:

void LinuxServerSocket::start_workloop(const ServerWorkers& worker) {internal_worker = worker;std::vector<epoll_event> events(max_epoll_contains);while (!shell_terminate) {int nfds = epoll_wait(epfd, events.data(), max_epoll_contains, -1);for (int i = 0; i < nfds; ++i) {int current_fd = events[i].data.fd;if (current_fd == socket_fd) {handle_new_connections(); // 新连接 -> accept_callback} else {react_clients(current_fd); // 数据 -> receiving_callback}}}
}

​ 这里就是一个经典的Reactor设计模式代码的流程:

  1. 注册事件:Reactor 注册 socket 和其关注的事件(如 EPOLLIN)。
  2. 等待事件:调用 epoll_wait()(或 select/poll)。
  3. 事件分发:将就绪事件分发给对应的事件处理器。
  4. 执行回调:事件处理器完成业务逻辑。

​ 在上面这里的 epoll_wait()Synchronous Event Demultiplexer(同步事件分发器),accept_callbackreceiving_callback 是事件处理器。


1.4 Reactor 的特点

  • 被动反应:Reactor 是“被动”的,只能处理已就绪的事件。
  • 同步 I/O:内核只负责通知“可读/可写”,真正的 read()/write() 由应用程序完成。
  • 适合高并发 I/O:结合 epoll,可以处理成千上万的连接。

补充:Proactor 设计模式

Proactor 的定义

  • Proactor 模式是一种异步非阻塞 I/O 模型。它的核心思想是:当 I/O 操作完成后,才通知应用程序,并把操作结果(包括读取的数据或写入的字节数)一并传递给应用程序。

    可以把 Proactor 模式想象成一个“送餐上门系统”:

    1. 你(应用程序) 去餐厅点餐并付款。
    2. 老板(操作系统) 告诉你:“饭好了会给你送过来。”
    3. 你在座位上(应用程序继续做其他事情) 不用管。
    4. 饭好了,服务员把餐端到你面前(I/O 操作完成,操作系统通知应用程序并传递结果)

一句话理解:

Proactor 模式中,应用程序只提交操作请求,内核在后台完成 I/O 后直接调用回调通知


核心组件:
  • 异步操作发起者 (Asynchronous Operation Initiator):应用程序发起异步 I/O 操作(例如,aio_read,在 Windows 上是 ReadFileEx)。
  • 异步事件多路分发器 (Asynchronous Event Demultiplexer):操作系统内核负责管理和完成异步 I/O 操作。
  • 完成处理器 (Completion Handler):操作系统在 I/O 操作完成后,会调用应用程序注册的这个回调函数,并将操作结果(如读取到的数据)作为参数传递给它。
工作流程:
  1. 应用程序发起一个异步 I/O 操作(例如,read 到某个缓冲区)。
  2. 操作系统内核接管这个 I/O 操作,立即返回,应用程序可以继续执行其他任务。
  3. 当 I/O 操作在内核中完全完成后(数据已经读取到缓冲区,或者数据已经发送完毕),内核会通知应用程序。
  4. 操作系统调用应用程序注册的完成处理器,将 I/O 操作的结果传递给它。

Proactor 的工作流程

  1. 应用程序发起异步操作(如 aio_read() 或 Windows IOCP 的 ReadFileEx())。
  2. 内核异步完成 I/O。
  3. 内核通知应用程序(通过回调、完成端口等机制)。
  4. 应用程序直接处理已完成的数据,无需再调用 read()

Reactor vs Proactor 对比

特点ReactorProactor
I/O 类型同步非阻塞 I/O异步 I/O
谁执行 I/O应用程序主动 read/write内核完成 I/O
触发时机通知“就绪”通知“完成”
常用平台epoll (Linux)、select/pollIOCP (Windows)、POSIX AIO

类比:

  • Reactor:门铃响了,你要去开门拿快递。
  • Proactor:快递小哥直接把快递送进家里,你只需处理包裹。

为什么项目选择 Reactor
  • Linux 原生提供的 epoll就绪通知 模型,不会替咱们完成 recv()
  • Proactor 在 Linux 中实现比较复杂,需要 io_uring 或 POSIX AIO,而 epoll + Reactor 模式成熟且高效。
http://www.xdnf.cn/news/16260.html

相关文章:

  • 关于自定义域和 GitHub Pages(Windows)
  • 基于springboot的候鸟监测管理系统
  • pycharm安装教程-PyCharm2023安装详细步骤【MAC版】【安装包自取】
  • Logstash 多表增量同步 MySQL 到 Elasticsearch:支持逻辑删除与热加载,Docker 快速部署实战
  • 【Android】桌面小组件开发
  • RAG面试内容整理-3. 向量检索原理与常用库(ANN、FAISS、Milvus 等)
  • 三坐标和激光跟踪仪的区别
  • 【源力觉醒 创作者计划】ERNIE-4.5-VL-28B-A3B 模型详解:部署、测试与 Qwen3 深度对比测评
  • OmoFun网页版官网入口,动漫共和国最新地址|官方下载地|打不开
  • Cacti命令执行漏洞分析(CVE-2022-46169)
  • qt5静态版本对应的pcre编译
  • 数据标注与AI赋能出版行业数智化转型|光环云张鹏出席“智启未来”沙龙并作主题分享
  • 输电线路观冰精灵在线监测装置:科技赋能电网安全的新利器
  • 「源力觉醒 创作者计划」文心一言VSDeepSeek
  • 从数据脱敏到SHAP解释:用Streamlit+XGBoost构建可复现的川崎病诊断系统
  • 用SSD实现AI RAG性能升级,铠侠发布AiSAQ新版本
  • Ubuntu22 上,用C++ gSoap 创建一个简单的webservice
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-24,(知识点:二极管基础知识,单向导电性)
  • 【09】C#入门到精通——C# 结构体对齐 与 常用数据 对应关系
  • CF每日5题(1500-1600)
  • node.js中的path模块
  • 技嘉z370主板开启vtx
  • windows11通过wsl安装Ubuntu到D盘,安装docker及宝塔面板
  • 【STM32】FreeRTOS 任务的删除(三)
  • 《 java 随想录》| 数组
  • Java学习日记_廖万忠
  • 支持OCR和AI解释的Web PDF阅读器:解决大文档阅读难题
  • uni-appDay02
  • #来昇腾学AI 【十天成长计划】大模型LLM Prompt初级班
  • Java学习----工厂方法模式