io_uring实现异步大块数据到文件
data-ad-format="fluid"
data-ad-layout-key="-7k+ex-4a-9w+4a">
相关文章:io_uring实现异步大块数据到文件 io_uring实现高效大文件多线程写入
使用 io_uring 实现异步写入 16MB-64MB 数据到文件(完整代码)
io_uring 是 Linux 高性能异步 I/O 框架,适用于大文件写入场景。以下是一个完整示例,将 16MB~64MB 的随机数据异步写入文件,并确保高效性和正确性。
1. 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <liburing.h> #include <sys/stat.h>
#define BUF_SIZE (16 * 1024 * 1024) // 16MB 缓冲区(可调整至64MB) #define FILE_NAME "large_file.bin"
// 初始化io_uring int setup_uring(struct io_uring *ring, unsigned entries) { int ret = io_uring_queue_init(entries, ring, 0); if (ret < 0) { perror("io_uring_queue_init"); exit(EXIT_FAILURE); } return ret; }
// 生成随机数据 void generate_data(char *buf, size_t size) { for (size_t i = 0; i < size; i++) { buf[i] = rand() % 256; // 填充随机字节 } }
// 异步写入文件 void async_write(struct io_uring *ring, int fd, char *buf, size_t size) { struct io_uring_sqe *sqe = io_uring_get_sqe(ring); if (!sqe) { fprintf(stderr, "Failed to get SQE\n"); exit(EXIT_FAILURE); }
io_uring_prep_write(sqe, fd, buf, size, 0); // 异步写入 io_uring_sqe_set_data(sqe, buf); // 关联缓冲区(用于后续释放)
io_uring_submit(ring); // 提交请求 }
int main() { struct io_uring ring; int fd; char *buf; size_t size = BUF_SIZE;
// 1. 初始化io_uring setup_uring(&ring, 8); // 8个SQE(可调整)
// 2. 创建文件并分配缓冲区 fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); }
buf = malloc(size); if (!buf) { perror("malloc"); exit(EXIT_FAILURE); }
// 3. 生成随机数据并异步写入 generate_data(buf, size); async_write(&ring, fd, buf, size);
// 4. 等待写入完成 struct io_uring_cqe *cqe; int ret = io_uring_wait_cqe(&ring, &cqe); if (ret < 0) { perror("io_uring_wait_cqe"); exit(EXIT_FAILURE); }
if (cqe->res < 0) { fprintf(stderr, "Write error: %s\n", strerror(-cqe->res)); exit(EXIT_FAILURE); }
printf("Successfully wrote %zu bytes to %s\n", size, FILE_NAME);
// 5. 清理资源 io_uring_cqe_seen(&ring, cqe); // 标记CQE已处理 io_uring_queue_exit(&ring); // 释放io_uring free(buf); close(fd);
return 0; }
|
2. 关键点解析
(1)io_uring 核心步骤
初始化 io_uring
提交异步写入请求
io_uring_get_sqe():获取一个空闲的提交队列项(SQE)。
io_uring_prep_write():设置异步写入操作。
io_uring_submit():提交请求到内核。
等待完成事件
资源释放
(2)性能优化建议
缓冲区对齐:使用 posix_memalign 分配对齐的内存(减少内核拷贝开销)。 posix_memalign((void**)&buf, 4096, size); // 4K对齐
批量提交:一次性提交多个写入请求(利用 io_uring 的批处理能力)。
轮询模式:启用 IORING_SETUP_SQPOLL 减少系统调用(需root权限)。
(3)扩展至64MB数据
3. 编译与运行
1 2
| gcc -o io_uring_write io_uring_write.c -luring ./io_uring_write
|
输出示例:
1
| Successfully wrote 16777216 bytes to large_file.bin
|
4. 验证写入结果
1 2
| ls -lh large_file.bin # 检查文件大小 md5sum large_file.bin # 验证数据完整性
|
5. 总结
组件作用io_uring提供异步I/O接口,避免阻塞线程。SQE/CQE提交队列(SQE)和完成队列(CQE)实现高效事件通知。缓冲区管理大内存分配需考虑对齐和分块,避免内存碎片。
此代码适用于 大文件写入、数据库日志、高性能存储 等场景,通过异步I/O最大化磁盘吞吐。
io_uring 异步写入大块数据到文件, io_uring 实现异步文件写入, io_uring 16MB-64MB 数据写入, io_uring 异步IO实现代码, io_uring 大数据写入文件教程, io_uring 异步写入性能优化, io_uring 文件操作示例代码, io_uring 异步IO编程指南, io_uring 大块数据处理方法, io_uring 写入文件完整代码示例