epoll —— Linux 高性能 I/O 多路复用详解

epoll(详解)

epoll 是 Linux 提供的高性能 I/O 多路复用机制,适合在大量并发连接场景下使用。相比传统的 select/poll,epoll 将被监控的描述符注册在内核中,内核维护就绪列表并通过事件通知用户态,从而实现更低的开销和更好的扩展性。

核心对比:select / poll / epoll

机制 工作方式 fd数量限制 性能 注释
select 每次传入全部 fd 并遍历 1024(默认) O(n) 需要复制 fd 集合到内核
poll 传入结构体数组并遍历 无限制 O(n) 避免了 fd 集合位图限制
epoll fd 在内核注册,事件触发时返回 无限制 O(1) 摘要 内核维护就绪链表,减少遍历开销

epoll 的核心数据结构

  • 红黑树:存储所有已注册(监控)的 fd
  • ready list(就绪链表):内核记录已经就绪的 fd,epoll_wait 从该链表返回事件
  • 回调/事件:用户通过 epoll_ctl 指定事件类型(例如 EPOLLIN / EPOLLOUT

三个主要系统调用

  • epoll_create1(flags):创建 epoll 实例(推荐使用 epoll_create1(0)
  • epoll_ctl(epfd, op, fd, &event):向 epoll 实例添加 / 修改 / 删除 fd
  • epoll_wait(epfd, events, maxevents, timeout):等待并返回就绪事件列表

LT(Level-Triggered) vs ET(Edge-Triggered)

模式 含义 特点
LT 水平触发 默认模式,只要缓冲区有数据,每次 epoll_wait 都会返回该 fd
ET 边缘触发 仅在状态变化时通知一次,需要用户配合非阻塞 I/O 并循环读取直到 EAGAIN

ET 模式适合高并发且追求更低系统调用次数的场景,但对程序要求更高:必须将 fd 设为非阻塞,并在收到一次事件后循环读/写直到返回 EAGAIN。否则可能出现“遗漏”数据的情况。

Reactor 模式与 epoll 的结合

Reactor 模式由三部分组成:Event Loop(事件循环)、Dispatcher(事件分发)、Handler(事件处理)。epoll 常被用作底层的事件分发机制:

  • Event Loop:调用 epoll_wait 获取就绪事件
  • Dispatcher:将就绪事件派发给对应的 Handler(如读写处理函数)
  • Handler:执行具体的 I/O 读写与业务逻辑

参考资料