liburing - cat
结合上回,大部分代码是样板代码,liburing 是为了简化我们手工调用 io_uring 实现的一个包装库
接下来用 liburing 实现 cat
CQE
先看代码
int get_completion_and_print(struct io_uring *ring) {
struct io_uring_cqe *cqe;
int ret = io_uring_wait_cqe(ring, &cqe);
if (ret < 0) {
perror("io_uring_wait_cqe");
return 1;
}
if (cqe->res < 0) {
fprintf(stderr, "Async readv failed.\n");
return 1;
}
struct file_info *fi = io_uring_cqe_get_data(cqe);
int blocks = (int) fi->file_sz / BLOCK_SZ;
if (fi->file_sz % BLOCK_SZ) blocks++;
for (int i = 0; i < blocks; i ++)
output_to_console(fi->iovecs[i].iov_base, fi->iovecs[i].iov_len);
io_uring_cqe_seen(ring, cqe);
return 0;
}
这里我们不用再自己操心各种内存屏障的问题,对 cqe 的操作通过 liburing 完成。
提交 SQE
同样地,提交部分,也全部通过 liburing 操作 SQE
/* Get an SQE */
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
/* Setup a readv operation */
io_uring_prep_readv(sqe, file_fd, fi->iovecs, blocks, 0);
/* Set user data */
io_uring_sqe_set_data(sqe, fi);
/* Finally, submit the request */
io_uring_submit(ring);
初始化和清理
初始化 liburing 使用
io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
程序退出前,清理
io_uring_queue_exit(&ring);
总结
总体代码量减少很多,并且不用手工 mmap 和考虑内存屏障问题。