linux 2.6以上内核提供以下几个系统调用来支持aio:
1、 SYS_io_setup:建立aio 的context
2、 SYS_io_submit: 提交I/O操作请求
3、 SYS_io_getevents:获取已完成的I/O事件
4、 SYS_io_cancel:取消I/O操作请求
5、 SYS_io_destroy:毁销aio的context
nginx中将aio和epoll事件模型(假设nginx使用epoll事件模型)组合起来使用,当请求的I/O操作完成时调用epoll相关函数通知应用程序来读取。组合的关键点在于使用了eventfd对象,那什么是eventfd呢?有关eventfd的详解资料参考http://linux.die.net/man/2/eventfd。
nginx在woker工作进程启动后初始化epoll事件模型时初始化aio(ngx_epoll_aio_init函数负责aio的初始化)。实现原理如下:在aio初始化时调用eventfd系统调用创建一个eventfd对象,eventfd系统调用返回一个与eventfd对象关联的文件描述符,设置该描述符为非阻塞并添加到epoll中,当该描述符可读时epoll_wait函数返回调用read函数读取当前完成的I/O操作个数,我们通过调用SYS_io_getevents系统调用就可以获取已完成的I/o事件。但eventfd描述符什么时候可读呢?这需要在提交I/O事件时将eventfd与aio关联起来(实现代码在ngx_file_aio_read函数中),提交I/O事件后如果I/O事件已完成就将当前完成的事件个数写入到eventfd描述符相关的计数器中并标识eventfd可读。下面来看看nginx中与aio相关的源代码:
ngx_epoll_aio_init函数:
static void
ngx_epoll_aio_init(ngx_cycle_t *cycle, ngx_epoll_conf_t *epcf)
{
int n;
struct epoll_event ee;
/***调用eventfd系统调用新建一个eventfd对象,第二个参数中的0表示eventfd的计数器初始值为0,
系统调用成功返回的是与eventfd对象关联的描述符***/
ngx_event