I/O 多路转接之 epoll:高并发服务器的性能利器
目录
一、epoll 核心优势:解决 select/poll 的痛点
二、epoll 工作原理:红黑树 + 就绪队列
核心流程
三、epoll 关键系统调用
1. epoll_create:创建 epoll 实例
2. epoll_ctl:管理监听的描述符
3. epoll_wait:等待就绪事件
四、epoll 的两种工作模式
1. 水平触发(LT,默认模式)
2. 边缘触发(ET)
五、代码示例:基于 epoll 的多客户端服务器
六、epoll 的适用场景
七、总结
在高并发网络编程场景中,select 和 poll 因自身缺陷(如描述符数量限制、遍历开销大等)逐渐力不从心。而 epoll 作为 Linux 下高性能的多路 I/O 复用技术,凭借其高效的事件通知机制,成为处理海量连接的 “性能利器”。
一、epoll 核心优势:解决 select/poll 的痛点
与 select/poll 相比,epoll 从根本上优化了高并发场景下的性能:
| 问题 | select/poll 表现 | epoll 表现 |
|---|---|---|
| 描述符数量限制 | 受限于 FD_SETSIZE(通常 1024) |
无限制,仅受系统资源约束 |
| 遍历开销 | 线性扫描所有描述符(时间复杂度 O(n)) | 直接获取就绪描述符(时间复杂度 O(1)) |
| 内存拷贝开销 | 每次调用需拷贝所有描述符到内核态 | 仅注册时拷贝,后续无额外开销 |
二、epoll 工作原理:红黑树 + 就绪队列
epoll 内部通过 “红黑树 + 就绪队列” 实现高效事件管理:
- 红黑树:存储所有需要监听的文件描述符(通过
epoll_ctl注册)。 - 就绪队列:当描述符就绪时,内核直接将其加入队列,避免遍历所有描述符。
核心流程
- 注册阶段:通过
epoll_ctl将描述符加入红黑树,内核为其注册回调函数。- 就绪通知:当描述符就绪时,回调函数将其加入就绪队列。
- 获取就绪事件:
epoll_wait直接从就绪队列中获取事件,无需遍历红黑树。
三、epoll 关键系统调用
1.
epoll_create:创建 epoll 实例#includeint epoll_create(int size);
- 作用:创建一个
epoll实例(本质是内核维护的红黑树和就绪队列)。- 参数:
size已被废弃(只需传入大于 0 的值即可)。- 返回值:
epoll实例的文件描述符(需通过close关闭)。
2.
epoll_c









