异步I/O:如何获取I/O请求中代码"认为"已写入的字节数?
POSIX异步IO获取实际写入字节数的方法
在使用aio.h的异步IO操作中,完全可以获取请求完成后实际写入的字节数,核心是用aio_return()函数,配合aio_error()做前置检查,具体操作如下:
核心函数用法
异步写请求提交后,必须等请求完成(不管成功还是失败),才能调用aio_return()获取结果。而且这个函数只能调用一次,调用后会清空相关状态。
步骤:- 用
aio_error()检查请求状态:返回EINPROGRESS说明请求还在进行,需要等待;返回0说明请求成功;返回其他值说明请求失败。 - 请求成功时,
aio_return()的返回值就是实际写入的字节数,正常情况下应该和你在struct aiocb中设置的aio_nbytes一致;请求失败时,aio_return()返回的是对应的错误码(和errno取值一致)。
- 用
代码示例
#include <aio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> int main() { int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { perror("open failed"); exit(EXIT_FAILURE); } char buf[] = "test async write"; struct aiocb cb = {0}; cb.aio_fildes = fd; cb.aio_buf = buf; cb.aio_nbytes = strlen(buf); // 若需要指定偏移量,设置cb.aio_offset // 提交异步写请求 if (aio_write(&cb) == -1) { perror("aio_write submit failed"); close(fd); exit(EXIT_FAILURE); } // 等待请求完成 while (aio_error(&cb) == EINPROGRESS) { sched_yield(); // 让出CPU,避免忙等 } // 获取结果 int err = aio_error(&cb); if (err == 0) { ssize_t written = aio_return(&cb); printf("实际写入 %zd 字节(预期 %zd)\n", written, cb.aio_nbytes); if (written != cb.aio_nbytes) { fprintf(stderr, "警告:写入字节数与预期不符,可能是磁盘满或权限问题\n"); } } else { fprintf(stderr, "异步写失败:%s\n", strerror(err)); } // 同步并关闭文件 if (aio_fsync(O_SYNC, &cb) == -1) { perror("aio_fsync failed"); } close(fd); return 0; }针对你的场景的排查建议
你遇到大量文件长度为0的情况,结合异步IO的特性,可能的原因包括:- 异步请求提交失败:你可能没检查
aio_write()的返回值,如果提交时就失败(比如文件打开错误、参数非法),自然不会有写入。 - 请求执行失败:比如磁盘空间不足、文件权限错误,此时
aio_error()会返回对应错误码,比如ENOSPC、EACCES。 - 请求未完成就关闭文件:如果在异步写还没结束时就调用
close(),会导致写入被中断,文件可能停留在0长度。 - aiocb结构体被提前释放/修改:多线程场景下,如果
struct aiocb是栈上分配的,线程退出后结构体被销毁,异步IO的后续操作会出问题。
- 异步请求提交失败:你可能没检查
内容的提问来源于stack exchange,提问作者bob.sacamento
相关产品推荐
相关产品推荐

