io_uring 入门
io_uring 是 Linux 内核 5.1 版本引入的异步 I/O 框架,
#原理
#代码组织
完整的 io-uring 由内核 syscall、liburing 库、用户态程序三部分组成。
- 内核提供了
io_uring_register
,io_uring_setup
,io_uring_enter
三个 syscall 接口。 - liburing 库提供了
io_uring_queue_init
,io_uring_get_sqe
,io_uring_wait_cqe
等函数。 - 用户态程序通过 liburing 库调用内核 syscall 接口,实现 I/O 请求的提交和完成。
#核心结构
每个 io_uring 实例由一个 struct io_uring
结构体表示。
1 | struct io_uring { |
每个 io_uring 实例包含两个环形队列:
- submission queue (SQ):提交队列,用于提交 I/O 请求。
- completion queue (CQ):完成队列,用于接收 I/O 请求的完成结果。
#使用方式
应用层通过 io_uring_queue_init
初始化一个 io_uring 实例。
1 | struct io_uring ring; |
应用层通过 io_uring_get_sqe
创建 SQE(Submission Queue Entry) 结构体,并设置 I/O 请求的参数: 操作类型、文件描述符、缓冲区、偏移量等。可以创建多个 SQE 结构体,并设置不同的私有数据。
1 | struct io_uring_sqe *sqe; |
提交后,应用层通过 io_uring_wait_cqe
等待已完成的 I/O 请求,并获取完成结果。
1 | struct io_uring_cqe *cqe; |
#工作模式
- 中断模式 (默认): 在
io_uring_enter
时,采用中断模式,等待 CQ 中出现完成的 IO 请求。 IORING_SETUP_IOPOLL
在io_uring_enter
时,采用 polling 而非中断模式,等待 CQ 中出现完成的 IO 请求。IORING_SETUP_SQPOLL
创建一个专用的内核线程 polling SQ 并处理 IO。IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL
睡眠等待 CQE 完成。