一、背景与核心问题
高并发网络编程的核心在于:如何高效处理大量 I/O 事件。两种经典模型:
-
Reactor:同步非阻塞 + 事件通知
-
Proactor:异步 I/O + 完成通知
本质区别在于:谁负责完成 I/O 操作
二、Reactor 模型(反应器)
1. 核心思想
-
内核只负责通知事件就绪
-
用户线程负责执行实际 I/O 操作(read/write)
2. 流程
1. 注册 socket 到事件多路复用器(epoll/select)
2. 等待事件(可读/可写)
3. 事件就绪 → 回调 handler
4. handler 中执行 read/write
3. 特点
-
同步非阻塞
-
控制灵活
-
编程复杂度较低(相对 Proactor)
4. 典型代码(Python 简化版)
import selectors
import socket
sel = selectors.DefaultSelector()
def accept(sock):
conn, addr = sock.accept()
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn):
data = conn.recv(1024)
if data:
conn.send(data) # echo
else:
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('localhost', 8888))
sock.listen()
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, _ in events:
callback = key.data
callback(key.fileobj)
👉 特点:select() 只告诉你"可以读了",但 read 是你自己调用的
三、Proactor 模型(前摄器)
1. 核心思想
-
内核负责完成 I/O 操作
-
完成后通知用户(completion event)
2. 流程
1. 提交异步 I/O 请求(read/write)
2. 内核执行实际 I/O
3. 完成后通知(回调/事件)
4. 用户处理结果
3. 特点
-
真正异步
-
更高性能潜力(减少用户态参与)
-
编程复杂度更高
-
依赖操作系统支持(如 Windows IOCP)
4. 典型代码(Python asyncio,本质接近 Proactor)
import asyncio
async def handle(reader, writer):
data = await reader.read(100)
writer.write(data)
await writer.drain()
writer.close()
async def main():
server = await asyncio.start_server(handle, '127.0.0.1', 8888)
async with server:
await server.serve_forever()
asyncio.run(main())
👉 特点:await reader.read() 表示:
-
你提交了 I/O 请求
-
完成后才返回(期间不阻塞线程)
四、核心区别总结
| 维度 | Reactor | Proactor |
|---|---|---|
| I/O 执行者 | 用户线程 | 内核 |
| 通知类型 | 就绪通知 | 完成通知 |
| I/O 类型 | 同步非阻塞 | 异步 |
| 编程复杂度 | 中 | 高 |
| 性能潜力 | 高 | 更高 |
| 典型实现 | epoll / select | IOCP / aio |
五、类比理解(非常关键)
假设你点外卖:
-
Reactor
-
店员说:"你的餐可以取了"
-
👉 你自己去拿(read)
-
-
Proactor
-
店员帮你送到桌上
-
👉 你只需要吃(处理结果)
-
六、实际应用
Reactor 常见:
-
Redis
-
Nginx
-
Netty(默认)
Proactor 常见:
-
Windows IOCP
-
Boost.Asio(部分模式)
-
Python asyncio(抽象层接近)
七、选型建议
-
Linux 高并发服务 → Reactor(epoll 足够强)
-
Windows 平台 → Proactor(IOCP)
-
追求极致异步 → Proactor
-
简洁与可控 → Reactor
八、一句话总结
-
Reactor:你等通知,然后自己干活
-
Proactor:你提交任务,系统帮你干完再通知你
如果需要,可以进一步补充:
-
多 Reactor(主从 Reactor)
-
Netty 中两种模型的实现细节
-
epoll vs IOCP 深度对比