IO 多路复用技术演进与原理深度解析
本文档是 IO 多路复用深度剖析 项目的理论部分
项目地址
GitHub: https://github.com/d60-Lab/io-multiplexing-deep-dive
# 克隆项目并运行测试
git clone git@github.com:d60-Lab/io-multiplexing-deep-dive.git
cd io-multiplexing-deep-dive
ulimit -n 10240
cargo build --release
cd scripts && ./benchmark.sh
本文档结合实际代码和测试数据,深入剖析五种 IO 多路复用技术的原理、性能和适用场景。
目录
问题背景:C10K 问题
什么是 C10K 问题?
C10K 指的是服务器如何支持 10,000 个并发连接 (Concurrent 10 Thousand)。在 2000 年左右,这是一个巨大的技术挑战。
为什么会有这个问题?
1. 传统模型的资源限制
每连接一个线程模型:
- 每个线程栈空间:2-8 MB
- 10,000 个线程 = 20-80 GB 内存(仅栈空间!)
- 线程上下文切换开销:O(n)
- 系统调度开销巨大
2. 具体瓶颈
资源消耗示例:
- 1 个连接 = 1 个线程
- 1 个线程 = 2 MB 栈 + 内核数据结构
- 10,000 连接 = 20 GB + 大量上下文切换
3. 为什么不能简单增加线程?
- 内存墙:物理内存有限
- 调度墙:CPU 时间片轮转,上下文切换成本高
- 锁竞争:大量线程导致锁争用
技术演进路线
时间线 | 技术 | 复杂度 | 并发能力 | 备注
-------|----------|--------|----------|------------------
1980s | Blocking | O(1) | < 100 | 每连接一个线程
1990s | select | O(n) | < 1024 | FD_SETSIZE 限制
1997 | poll | O(n) | > 1024 | 突破 fd 限制
1999 | epoll | O(1) | > 100K | Linux 2.6+
2000 | kqueue | O(1) | > 100K | FreeBSD/macOS
2019 | io_uring | O(1) | > 1M | Linux 5.1+
2020s | async | O(1) | > 1M | 协程 + 事件循环
