这一篇要解决什么?

前面你已经有了:

  • ✔ 阻塞版 TCP 服务端(能跑)
  • ✔ 线程池接入(能并发)
  • ✔ 服务骨架(有结构)

但还有一个根本问题:

❌ 一个连接 ≈ 一个线程(线程会被阻塞)

这一篇要回答:

如何用“更少线程”,处理“更多连接”?

一、先复盘你走过的三种模型

1️⃣ 单线程阻塞(第一篇)

accept → read → write → close

👉 问题:

  • 串行处理 ❌
  • 一个慢请求拖死全局 ❌

2️⃣ 线程池 + 阻塞 IO(第二篇)

主线程:
accept
↓
线程池:
read → write

👉 优点:

  • 能并发 ✔

👉 问题:

一个连接 → 占一个线程 ❌

3️⃣ 服务骨架(第三篇)

read → parse → dispatch → encode → write

👉 优点:

  • 有结构 ✔
  • 可扩展 ✔

👉 问题:

❌ 底层 IO 还是阻塞的

二、真正的瓶颈在哪?

核心问题不是线程池,而是:

线程被阻塞了


举个真实场景

10000 个客户端连接

如果每个连接:

read() 阻塞

👉 你需要:

10000 个线程 ❌(直接崩)

三、关键转折点:非阻塞 IO

阻塞 IO

read(fd, ...)

👉 没数据:

❌ 卡住线程

非阻塞 IO

fcntl(fd, F_SETFL, O_NONBLOCK);

👉 没数据:

✔ 立刻返回(不会卡住)

四、但新问题来了

如果不阻塞:

read(fd)

👉 没数据 → 返回
👉 你就得:疯狂轮询(while循环)

👉 CPU 会炸

五、这就引出 epoll

epoll 做什么?

告诉你:哪些 fd “可以读 / 可以写”

核心思想

你不用问“有没有数据”

内核主动告诉你“有数据了”

六、epoll 模型(核心图)

               ┌────────────┐
               │   epoll    │
               └────────────┘
                     │
        ┌────────────┼────────────┐
        ▼            ▼            ▼
     fd1就绪      fd2就绪      fd3就绪
        │            │            │
        ▼            ▼            ▼
     read         read         read

七、核心 API(你先有个印象)

epoll_create()
epoll_ctl()
epoll_wait()

最关键的是:

epoll_wait(...)

👉 返回:

所有“就绪的 fd 列表”

八、从线程池模型 → epoll 模型

线程池模型

一个连接 → 一个线程

epoll 模型

一个线程 → 管理多个连接

👉 本质变化:

线程不再绑定连接,而是绑定“事件”

九、Reactor 模型(核心思想

你会听到一个词:

Reactor


Reactor 是什么?

事件驱动的处理模型


模型图

epoll_wait()
│
▼
有事件发生(fd ready)
│
▼
分发给 handler
│
▼
处理 read / write

对应你现在的代码

fd ready
↓
ConnectionHandler
↓
parse / dispatch / encode

👉 你第三篇的结构:

已经是 Reactor 的“处理层”

十、把你现在的认知彻底打通

你现在有三层:

第一层:IO模型

模型 特点
阻塞 IO 卡线程
非阻塞 IO 不卡线程
epoll 事件驱动

第二层:执行模型

模型 特点
单线程 串行
线程池 多线程
Reactor 少线程多连接

第三层:服务骨架

ConnectionHandler
↓
Parser
↓
Dispatcher
↓
Encoder

十一、最关键的跃迁(必须理解)

之前

线程 = 连接

之后

线程 = 事件循环
连接 = 状态机

👉 这句话非常重要。

十二、为什么 Nginx 能扛高并发?

因为:

一个线程

epoll

管理几万连接

👉 而不是:一个连接一个线程 ❌

十三、这一篇真正的价值

不是让你会写 epoll,而是:

你开始理解:

并发的本质不是线程多,而是“调度方式”不同

十四、你现在的完整认知图

线程池(执行引擎)
↓
阻塞 IO(简单模型)
↓
服务骨架(处理链)
↓
非阻塞 IO(不阻塞线程)
↓
epoll(事件通知)
↓
Reactor(统一调度模型)

十五、你现在达到了什么水平?

你已经:

✔ 理解 socket
✔ 理解 fd
✔ 理解线程池
✔ 理解服务骨架
✔ 理解阻塞 vs 非阻塞
✔ 理解 epoll 作用
✔ 理解 Reactor 思想

👉 这已经是:

服务端并发架构入门到进阶的完整闭环

最后一段(最重要)

你现在要记住一句话:

线程池解决“怎么执行”
epoll/Reactor 解决“什么时候执行”

👉 前三篇解决:怎么处理请求

👉 第四篇解决:什么时候处理请求(事件驱动)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐