玖叶教程网

前端编程开发入门

如何正确使用io_uring

#每日一点linux##计算机软件#

io_uring


io_uring 是一种新的 Linux 异步 I/O 操作方式,自 Linux 内核 5.1 版本开始引入。相较于传统的 Linux 异步 I/O 操作方式(如 epoll、kqueue、AIO 等),io_uring 在性能、可扩展性和易用性上都有显著优势。io_uring 最初由 Jens Axboe 开发,旨在提供高效的异步 I/O 支持,以便可在用户空间中处理大量磁盘 I/O 请求。

io_uring 是一个 Linux 内核实现的底层机制,可以在用户空间中使用 LIBURING 库进行操作。LIBURING 是一个 C 库,提供了许多函数和相关数据类型,可用于创建、提交和处理 io_uring 请求。与其他异步 I/O 操作方式相比,io_uring 具有以下几个优点:

更低的 CPU 使用率:io_uring 利用了 Linux 的内核通信技术,将 操作系统的内核空间和用户空间之间的上下文切换减少到最小,从而极大地减少了 CPU 使用率的消耗。

更低的内存使用率:io_uring 处理 I/O 操作时,不需要创建额外的内存缓存区,从而降低了内存使用率的负担。

更高的并发性和可扩展性:io_uring 具有非常高的并发性和可扩展性,在高负载的情况下可以达到很好的性能。

更好的易用性:使用 io_uring API 的编程方式相对简单,适合开发者使用。

由于 io_uring 具有这些优点,因此它得到了广泛的应用,特别是在高负载、高并发的情况下,能够极大地提升系统的性能。


liburing

liburing 是一个 C 库,提供了 API 以在用户空间中操作 io_uring。liburing 通过封装 io_uring、提供请求池管理、请求提交和 I/O 结果处理等功能,实现了一种更易用、更高效的 I/O 操作方式,使开发人员可以更加方便地利用 io_uring 提升程序的性能。

liburing 的主要工作方式是通过一个 I/O 处理环(IO polling ring)与内核通信。这个 I/O 处理环包含了若干请求元素(struct io_uring_sqe),这些请求元素可以包含各种 I/O 请求,比如读、写、锁定、同步。每个请求元素都包含有请求的详细信息,以及一个回调函数指针,用于在请求完成时通知处理程序。处理程序可以将请求提交到 io_uring,等待请求完成的消息。一旦请求完成,处理程序就会从 io_uring 中获取完成请求的详细信息,并执行相应的回调函数进行处理。

与传统的 I/O 操作方式相比,liburing 提供了更高效、更易用的 API,使得开发人员可以轻松地使用 io_uring 进行异步多路 I/O 操作。liburing 已经得到了广泛的应用,特别是在高性能应用、网络服务器和分布式存储等场景中,可以显著提升程序的性能和可扩展性。

liburing 库提供了一些常用的方法,可以帮助程序员更轻松地使用 io_uring 进行异步 I/O 操作。以下是一些常用方法的介绍:

  • 1. io_uring_queue_init
int io_uring_queue_init(unsigned entries, struct io_uring_params *p, unsigned flags);

该方法用于初始化一个 io_uring,并返回一个文件描述符。`entries` 参数表示请求队列中的请求数,`flags` 参数表示初始化标志,`p` 参数用于传递自定义参数。

2. io_uring_prep_readv

void io_uring_prep_readv(struct io_uring_sqe *sqe, int fd, const struct iovec *iovecs, unsigned nr_iovecs, off_t offset);

该方法用于准备一个读取操作的请求,将其添加到请求队列中。`sqe` 参数表示请求元素指针,`fd` 参数表示文件描述符,`iovecs` 参数表示请求数据,`nr_iovecs` 表示数据块数,`offset` 参数表示读取偏移量。

3. io_uring_prep_writev


void io_uring_prep_writev(struct io_uring_sqe *sqe, int fd, const struct iovec *iovecs, unsigned nr_iovecs, off_t offset);

该方法用于准备一个写入操作的请求,将其添加到请求队列中。`sqe` 参数表示请求元素指针,`fd` 参数表示文件描述符,`iovecs` 参数表示请求数据,`nr_iovecs` 表示数据块数,`offset` 参数表示写入偏移量。

4. io_uring_submit

long io_uring_submit(struct io_uring *ring);

该方法用于提交请求队列中的 I/O 操作请求,并等待所有请求完成。`ring` 参数表示 io_uring 对象。

5. io_uring_wait_cqe

int io_uring_wait_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr);

该方法用于等待 I/O 操作完成,并返回完成请求的元素。`ring` 参数表示 io_uring 对象,`cqe_ptr` 参数表示等待完毕并要返回的请求元素指针。

这些方法只是 liburing 库中的一部分,liburing 还有其他常用方法,比如`io_uring_prep_accept`、`io_uring_prep_connect`、`io_uring_prep_poll_add` 等,根据具体的 I/O 操作需要使用合适的方法。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <time.h>
#include <liburing.h>

int main() {
    // 1. 打开文件并获取文件的大小
    int fd = open("file.txt", O_RDONLY);
    if (fd < 0) {
        perror("open 文件失败");
        exit(-1);
    }
    struct stat file_stat;
    if (fstat(fd, &file_stat) < 0) {
        perror("获取文件大小失败");
        exit(-1);
    }
    const int file_size = file_stat.st_size;
    printf("文件大小为 %d bytes\n", file_size);

    // 2. 将文件映射到内存中
    void *file_mem = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (file_mem == NULL) {
        perror("文件映射失败");
        exit(-1);
    }

    // 3. 初始化 io_uring
    struct io_uring ring;
    io_uring_queue_init(8, &ring, 0);

    // 4. 注册缓冲区至 io_uring 中
    struct iovec iov;
    iov.iov_base = file_mem;
    iov.iov_len = file_size;
    struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
    io_uring_prep_readv(sqe, fd, &iov, 1, 0);
    io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE);
    int register_result = io_uring_register_files(&ring, &fd, 1);
    if (register_result < 0) {
        perror("io_uring_register 缓冲区失败");
        exit(-1);
    }

    // 5. 提交到 io_uring 并等待执行完成
    io_uring_submit(&ring);
    struct io_uring_cqe *cqe;
    io_uring_wait_cqe(&ring, &cqe);
    io_uring_cqe_seen(&ring, cqe);

    // 6. 反注册、解除映射和关闭文件描述符
    io_uring_unregister_files(&ring);
    munmap(file_mem, file_size);
    close(fd);

    return 0;
}

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言