I/O 多路复用: select,poll,epoll,io_uring

notion image
时间线演进:
  • 1990年代: select (POSIX标准,所有Unix都有)
  • 1997年: poll (System V Release 4)
  • 2002年: epoll (Linux 2.5.44)
  • 2019年: io_uring (Linux 5.1)
 
notion image
 
目前而言,网络 I/O 使用 epoll 已经足够,而涉及磁盘 I/O 的高性能存储框架用 io_uring 更多一些
 

应用情况

notion image
notion image
磁盘框架趋势
  • 传统数据库:多使用标准文件 I/O + fsync,或 Linux aio
  • 现代存储系统:开始转向 io_uring(Linux 5.1+)
  • 极限性能场景:使用 SPDK 的轮询模式(用户态驱动)
 

原理学习

1. epoll 的通知机制

notion image
epoll 是三个函数组成的一套机制,而不是单个函数。
 

2. epoll的工作模式:

水平触发(LT,Level-Triggered)
  • 默认模式
  • 只要文件描述符可读/可写,epoll_wait就会一直通知
  • 类似"只要有数据,就一直提醒你"
边缘触发(ET,Edge-Triggered)
  • 通过EPOLLET标志设置
  • 只在状态变化时通知一次
  • 类似"只在新数据到达时提醒一次"
  • 需要非阻塞I/O,必须一次性读完所有数据
// 设置ET模式
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET;  // 添加ET标志
ev.data.fd = sockfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
 
 

思考问题

1. 为什么 leveldb 使用直接I/O, 而没有使用 io_uring?

notion image

2. epoll 和Reactor 模式之间的区别?

Reactor 模式有单Reactor多线程模型 和 主从Reactor多线程模型,epoll 往往是用来实现 Reactor模型的机制,而不隶属于任何一个模型。
notion image
你觉得这篇文章怎么样?
YYDS
比心
加油
菜狗
views

Loading Comments...