返回
创建于
状态
公开

在 Linux 系统编程中,epoll 和 io_uring 是处理高并发 I/O 的两代核心技术。epoll 是长久以来的行业标准,而 io_uring 则是近年来 Linux 内核引入的“颠覆者”。

  1. epoll:传统的事件通知机制 epoll 属于同步非阻塞 I/O 模型。它的核心思想是:你把成千上万个连接交给内核看管,当某个连接有数据可读或可写时,内核通知你,你再自己去调用 read 或 write 提取数据。 工作流程
  • 注册:使用 epoll_ctl 将 Socket 加入监听队列。
  • 等待:调用 epoll_wait 阻塞,直到有事件发生。
  • 执行:用户进程被唤醒,手动发起系统调用进行数据拷贝。 痛点 * 频繁的系统调用:每次 epoll_wait 和后续的 read/write 都是系统调用,存在上下文切换开销。
    • 数据拷贝:内核缓冲区和用户缓冲区之间仍需进行数据拷贝。
    1. io_uring:下一代异步 I/O io_uring 是由 Jens Axboe 在 2019 年引入的,它实现了真正的异步 I/O。它不只是“通知”你,而是直接帮你把活干完。 核心机制:双环形队列 io_uring 在内核和用户空间之间共享两个环形队列(Ring Buffer),从而避免了大量的数据拷贝和系统调用:
    • 提交队列 (SQ - Submission Queue):用户把要做的任务(如“读这个文件”)放进去。
    • 完成队列 (CQ - Completion Queue):内核处理完后,把结果放进去,用户直接取。 为什么它更快?
    • 零系统调用(SQPOLL 模式):可以开启一个内核线程专门轮询 SQ,用户提交任务时完全不需要进行系统调用。 * 减少上下文切换:用户和内核通过共享内存通信,不再频繁地在用户态和内核态之间跳来跳去。
      • 支持广泛:不仅支持 Socket 网络编程,对磁盘文件 I/O 的加速也非常显著(这是 epoll 做不到的)。
      1. 核心对比 | 特性 | epoll | io_uring | |---|---|---| | I/O 模型 | 同步非阻塞 (IO Multiplexing) | 异步 (True Async) | | 通知方式 | 告诉你“好了,你可以来干活了” | 告诉你“活已经帮你干完了” | | 系统调用开销 | 高(每次事件触发都需要多次调用) | 极低(通过共享内存和批量提交) | | 适用范围 | 主要是网络 Socket | 网络 Socket + 磁盘文件 | | 内核版本要求 | 2.6+ (非常成熟) | 5.1+ (较新,推荐 5.10+) |
      2. 总结与建议
      • 什么时候用 epoll? 如果你的应用需要极高的兼容性(旧版 Linux),或者目前的性能瓶颈并不在系统调用开销上,epoll 依然是极其稳定且可靠的选择。
        • 什么时候用 io_uring? 如果你在追求极致性能(如高频交易、高性能 Web 服务器),或者需要处理大量磁盘 I/O(数据库、存储引擎),io_uring 是未来的方向。在最新的基准测试中,io_uring 的吞吐量通常能超越 epoll。