You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

epoll与io_uring谁更优?io_uring能否单SQE生成多CQE?

io_uring 持续读取模式与epoll的对比疑问

问题背景

使用io_uring时,每次完成前一个read请求后都需提交新的read请求,这在很多场景下并不符合直觉——通常我们只想持续从TCP连接读取数据。而epoll只需将文件句柄注册到内核的epoll对象一次,就能在有新数据可读时收到通知。(当然,“符合直觉”的定义是主观的。)

当然,epoll存在一个问题:必须重复调用read系统调用来获取实际数据,在这一点上io_uring显然更优。因此我的观点主要针对API的抽象语义。不过我也注意到,在某些场景下,重复提交read请求可能会给io_uring带来性能问题,例如拥有大量连接(如2万个)且均频繁进行短读取(如4字节)的服务器。

我是否忽略了什么?io_uring能否以单个submission-queue-entry(sqe)生成多个completion-queue-entry(cqe)的模式运行?

解答

io_uring确实支持单个SQE生成多个CQE的模式,核心是利用特定内核标志实现持续读取:

  • IORING_RECV_MULTISHOT标志:Linux内核5.19及以上版本支持。提交带该标志的IORING_OP_RECV(TCP套接字场景下与IORING_OP_READ等效)SQE后,内核会在每次有数据可读时生成一个CQE,直到连接关闭或主动取消该SQE。这种模式完全满足“持续读取TCP连接数据”的需求,无需在每次读取完成后重新提交请求。

  • 针对短读场景的性能优化:对于2万连接频繁短读取的场景,MULTISHOT模式能大幅减少用户态与内核态的交互开销——不需要反复向提交队列(SQ)写入条目、调用io_uring_submit,从根源上避免重复提交SQE带来的性能损耗。

  • 兼顾语义与性能:该模式既拥有类似epoll“一次注册、持续通知”的直观抽象语义,又保留了io_uring无需额外调用read系统调用的优势——数据直接由内核读取到指定缓冲区,CQE返回后即可直接处理数据,兼顾了使用体验和性能表现。

使用时需注意:要确保缓冲区大小能容纳单次读取的数据;若需终止持续读取,可通过io_uring_cancel取消对应的SQE。

内容的提问来源于stack exchange,提问作者levzettelin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:43:21