面试题答案
一键面试实现思路
- 初始化异步I/O上下文:使用
aio_context_t
结构体来管理异步I/O操作,通过io_setup
函数初始化上下文。 - 准备异步I/O请求:填充
struct iocb
结构体,指定文件描述符、操作类型(读或写)、数据缓冲区、偏移量等信息。 - 提交异步I/O请求:使用
io_submit
函数将iocb
结构体提交到异步I/O上下文,让内核开始执行异步操作。 - 等待异步I/O完成:使用
io_getevents
函数等待异步I/O操作完成,并获取操作结果。可以设置超时时间,避免无限期等待。
关键函数
- io_setup:初始化异步I/O上下文。
int io_setup(unsigned nr, aio_context_t *ctxp);
nr
:指定上下文可以处理的最大请求数。ctxp
:指向aio_context_t
结构体的指针,用于存储初始化后的上下文。
- io_destroy:销毁异步I/O上下文。
int io_destroy(aio_context_t ctx);
ctx
:要销毁的异步I/O上下文。
- io_submit:提交异步I/O请求。
int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp);
ctx
:异步I/O上下文。nr
:要提交的请求数量。iocbpp
:指向struct iocb
指针数组的指针。
- io_getevents:等待异步I/O操作完成并获取结果。
int io_getevents(aio_context_t ctx, long min_nr, long max_nr, struct io_event *events, struct timespec *timeout);
ctx
:异步I/O上下文。min_nr
:最少等待完成的请求数。max_nr
:最多获取的完成请求数。events
:用于存储完成事件的struct io_event
数组。timeout
:等待的超时时间,如果为NULL
则无限期等待。
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <aio.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 1024
#define MAX_REQUESTS 10
int main() {
aio_context_t ctx;
struct iocb iocbs[MAX_REQUESTS];
struct io_event events[MAX_REQUESTS];
char buffers[MAX_REQUESTS][BUFFER_SIZE];
int file_descriptors[MAX_REQUESTS];
int num_files = 5;
// 初始化异步I/O上下文
if (io_setup(MAX_REQUESTS, &ctx) != 0) {
perror("io_setup");
return 1;
}
// 打开文件并准备异步I/O请求
for (int i = 0; i < num_files; i++) {
char filename[20];
snprintf(filename, sizeof(filename), "file%d.txt", i);
file_descriptors[i] = open(filename, O_RDONLY);
if (file_descriptors[i] == -1) {
perror("open");
continue;
}
memset(&iocbs[i], 0, sizeof(struct iocb));
io_prep_pread(&iocbs[i], file_descriptors[i], buffers[i], BUFFER_SIZE, 0);
}
// 提交异步I/O请求
if (io_submit(ctx, num_files, (struct iocb **)&iocbs) != num_files) {
perror("io_submit");
goto cleanup;
}
// 等待异步I/O完成
if (io_getevents(ctx, num_files, num_files, events, NULL) != num_files) {
perror("io_getevents");
goto cleanup;
}
// 处理读取结果
for (int i = 0; i < num_files; i++) {
if (events[i].res < 0) {
perror("read error");
} else {
printf("Read %ld bytes from file%d.txt: %.*s\n", events[i].res, i, (int)events[i].res, buffers[i]);
}
close(file_descriptors[i]);
}
cleanup:
// 销毁异步I/O上下文
io_destroy(ctx);
return 0;
}
此代码示例展示了如何使用异步I/O在Linux系统中并行读取多个文件,避免阻塞主线程,从而提高性能。