news 2026/5/3 22:49:26

为什么会出现Reactor?IO模型的本质(从线程到协程 · 第3篇)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
为什么会出现Reactor?IO模型的本质(从线程到协程 · 第3篇)

系列第3篇|承接上一篇《线程池解决了什么?为什么还不够?》
本篇讲清楚:为什么线程池在高并发IO下仍然不够 → Reactor如何解决


一、先说结论(一定要记住)

👉 Reactor的核心思想只有一句话:

不要让线程等,等事件就绪再处理


二、线程池为什么在IO场景下不够用?


场景:高并发请求

1000个请求同时进来 ↓ 每个请求都要访问数据库 / 网络 ↓ 每个线程执行 IO 操作

❌ 传统线程池模型

线程1:发请求 → 等IO → 阻塞 线程2:发请求 → 等IO → 阻塞 线程3:发请求 → 等IO → 阻塞 ...

👉 结果:

线程全部卡住(等待IO) CPU空闲(但线程被占用)

👉 本质问题:

线程被“等待”浪费了


三、IO到底在干嘛?(本质理解)

一个IO操作,本质是:

发请求 → 等待数据返回 → 处理数据

👉 关键点:

等待阶段(最耗时) CPU不参与

👉 举个例子:

发送网络请求:1ms 等待响应:100ms 处理数据:1ms

👉 你会发现:

98%时间在“等”,不是在“算”


四、传统模型的问题在哪里?

传统模型是:

一个请求 = 一个线程

👉 但问题是:

线程在等IO时 → 什么都不干

👉 如果:

1000个请求 → 1000个线程

👉 就变成:

1000个线程在“发呆”

👉 所以问题不是:

线程不够

👉 而是:

线程被浪费


五、IO模型的演进(核心)


1️⃣ 阻塞IO(Blocking IO)

read(fd) ↓ 没有数据 → 阻塞

线程必须等


2️⃣ 非阻塞IO(Non-blocking IO)

read(fd) ↓ 没有数据 → 立即返回

👉 你要不停轮询:

while(true) { read(fd); }

👉 问题:

CPU空转(浪费)

3️⃣ IO多路复用(epoll / select)

👉 核心:

让操作系统帮你等

epoll_wait() ↓ 哪些fd有数据 → 返回

👉 你只处理:

ready 的连接

本质:

等待交给OS,处理交给线程


六、Reactor模型是什么?

👉 Reactor =IO多路复用 + 事件驱动


核心结构

Reactor ↓ 监听事件(epoll) ↓ 事件就绪 ↓ 分发给Handler处理

👉 简化流程:

1. 注册连接(fd) 2. 等待事件(epoll_wait) 3. 哪个fd ready 4. 调用对应处理逻辑

👉 图示:

[Client1] ─┐ [Client2] ─┼──> Reactor(epoll)──> Handler [Client3] ─┘

七、Reactor解决了什么问题?


1️⃣ 不再一个连接一个线程

从:1000连接 = 1000线程

👉 变成:

1000连接 = 少量线程 + epoll

2️⃣ 不再阻塞等待

👉 原来:

线程等IO

👉 现在:

线程只在“有数据时”执行

3️⃣ 极大提高线程利用率

👉 线程只做:

处理数据

👉 不再做:

等待

八、Reactor的本质(非常重要)

👉 Reactor不是“新技术”,而是:调度策略升级


👉 原来:

线程驱动任务

👉 现在:

事件驱动任务

👉 本质变化:

谁来触发执行?
模型触发方式
多线程线程调度
Reactor事件就绪

九、Reactor vs 线程池

维度线程池Reactor
模型任务驱动事件驱动
IO处理阻塞非阻塞
线程利用率
并发能力

👉 一句话总结:

线程池优化线程,Reactor优化IO


十、Reactor的局限性(很关键)


1️⃣ 编程复杂

回调地狱 状态机复杂 代码难维护

2️⃣ 不是“同步思维”

onRead → onWrite → callback

👉 不直观


3️⃣ 业务代码难写

逻辑被拆碎

👉 所以:

Reactor解决了性能问题,但带来了复杂度问题 (后面协程就是为了解决这个问题)


十一、为什么会出现协程?(铺垫下一篇)

👉 你会发现:

线程池 → 简单,但浪费线程 Reactor → 高效,但复杂

那有没有一种方式:

既不阻塞线程 又能写同步代码?

👉 答案是:

协程


👉 本质:用“同步写法”表达“异步执行


十二、统一模型(必须记住)

多线程:任务 = 线程 线程池:复用线程 Reactor:事件驱动 协程:任务调度

👉 再压缩一句:

Reactor解决“线程等待问题”,协程解决“代码复杂度问题”


十三、面试标准回答

Reactor模型主要是为了解决高并发IO场景下线程被阻塞的问题。在传统线程模型中,一个连接通常对应一个线程,当IO操作发生时,线程会阻塞等待,导致大量线程资源被浪费。

Reactor通过IO多路复用机制(如epoll),将多个连接注册到一个事件监听器上,当某个连接有数据就绪时再进行处理,从而避免线程在等待IO时被占用。

本质上,Reactor是将“线程驱动”转为“事件驱动”,从而提升线程利用率和系统吞吐能力。


十四、总结

👉 到这里你会发现:

Reactor已经解决了“线程等待问题”,但代码变得非常复杂。


👉 下一篇:

《协程到底解决了什么问题?》

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 22:47:24

从法证新手到效率达人:我的Autopsy 4.19.3工作流搭建与模块初探

从法证新手到效率达人:我的Autopsy 4.19.3工作流搭建与模块初探 第一次打开Autopsy时,面对密密麻麻的菜单和术语,我仿佛站在数字取证世界的入口处——既兴奋又迷茫。这款开源神器能分析磁盘镜像、恢复删除文件、解析浏览器历史,甚…

作者头像 李华
网站建设 2026/5/3 22:46:25

Select to Think:蒸馏 token 排序能力,效果平均提升24%

一句话总结 SLM 的效果差不是因为它不会,而是它没把正确答案排到第一;蒸馏排序能力让 SLM 效果平均提升 24% 论文标题:Select to Think: Unlocking SLM Potential with Local Sufficiency论文地址:http://arxiv.org/pdf/2604.2694…

作者头像 李华
网站建设 2026/5/3 22:37:32

Python调试器无法进入execute()内部?突破pdb限制:用sys.settrace+DB-API钩子实现语句级单步追踪(生产环境可用)

更多请点击: https://intelliparadigm.com 第一章:Python数据库调试的现状与挑战 Python 应用在连接和操作数据库时,常因环境差异、驱动兼容性、SQL 语法误用或事务管理疏漏而陷入难以复现的调试困境。开发者往往在本地运行正常,…

作者头像 李华
网站建设 2026/5/3 22:35:26

[简化版 GAMES 101] 计算机图形学 07:图形学投影完全推导

[简化版 GAMES 101] 计算机图形学 07:图形学投影完全推导Bilibili 同步视频0. 前置约定 📌一、正交投影 Orthographic Projection1.1 直观理解1.2 变换两步走平移矩阵缩放矩阵正交投影矩阵(最终)二、透视投影 Perspective Project…

作者头像 李华