---
title: libaio实现参考
description: "对于磁盘文件，文件的读取是同步的，导致线程读取文件时，处于阻塞状态。程序为了提升性能和磁盘的吞吐，程序会创建几个单独的磁盘读写线程，并通过信号量等机制进行线程间通信（同时带有锁）；显然线程多，锁多，会导致更多的资源抢占，从而导致系统整体性能下降。"
url: https://www.hikunpeng.com/document/detail/zh/perftuning/tuningtip/kunpengtuning_12_0069.html
sourcePath: /source/zh/perftuning/tuningtip/kunpengtuning_12_0069.html
indexId: 330ce78e96d26d7b2385db69cacedaa1289261f0cc604066b46fcc12696fe35b58
---
# libaio实现参考

对于磁盘文件，文件的读取是同步的，导致线程读取文件时，处于阻塞状态。程序为了提升性能和磁盘的吞吐，程序会创建几个单独的磁盘读写线程，并通过信号量等机制进行线程间通信（同时带有锁）；显然线程多，锁多，会导致更多的资源抢占，从而导致系统整体性能下降。

libaio提供了磁盘文件读写的异步机制，使得文件读写不用阻塞，结合epoll机制，实现一个线程可以无阻塞地运行，同时处理多个文件读写请求，提升服务器整体性能。下面是libaio+epoll的一个实现示例。

代码删除了变量初始化、异常判断等分支。


```
/* AIO的回调函数*/
void aio_callback(io_context_t ctx, struct iocb *iocb, long res, long res2)
{
/* 失败时-res为errno；成功时，res为真正读取的字节数；
iocb->u.c.buf为读取的内容*/
···
}
/*
* 使用libaio和epoll，对同一个文件的若干个不同偏移位置发起异步读取请求，
* 如对文件的偏移位置0、1024*1、1024*2、……、1024*127发起总共128个异步读取请求（读取1024字节）
*/
int libaio_epoll_read_file()
{
efd = eventfd(0, EFD_NONBLOCK);
fd = open(TEST_FILE, O_RDWR | O_CREAT | O_DIRECT, 0644);
io_setup(8192, &ctx);
for (int i = 0; i < NUM_EVENTS; i++) {
posix_memalign(&buf, ALIGN_SIZE, RD_WR_SIZE);
io_prep_pread(iocbs[i], fd, buf, RD_WR_SIZE, i * RD_WR_SIZE);
io_set_eventfd(iocbs[i], efd);
io_set_callback(iocbs[i], aio_callback);
}
io_submit(ctx, NUM_EVENTS, iocbs);
epfd = epoll_create(1);
epevent.events = EPOLLIN | EPOLLET;
epevent.data.ptr = NULL;
epoll_ctl(epfd, EPOLL_CTL_ADD, efd, &epevent);
while (i < NUM_EVENTS) {
epoll_wait(epfd, &epevent, 1, -1);
read(efd, &finished_aio, sizeof(finished_aio));
while (finished_aio > 0) {
r = io_getevents(ctx, 1, NUM_EVENTS, events, &tms);
for (j = 0; j < r; ++j) {
// 调用对应事件的回调函数，处理数据
((io_callback_t)(events[j].data))(
ctx, events[j].obj, events[j].res, events[j].res2);
}
}
}
}
```
