本文为 Linux 异步I/O编程系列文章的第二篇。本系列前面的文章链接如下:
Linux异步I/O编程
异步I/O,主要应用于如下场景:
(1) 通信aio:提升海量连接、网络io的性能,如 Web Servers, Proxy servers, LDAP servers, X-server等
(2) 磁盘/文件 aio:如数据库、IO密集型应用程序
(3) 以上两种组合:流内容服务(Streaming content servers), 如 video/audio/web/ftp,将磁盘的数据直接传给网络,不走文件->内存->网络这样的多次内存拷贝的路径。
前文对Linux 异步I/O进行了介绍,并给出了一个同时对2个文件进行异步I/O读取的代码示例。本文继续对文件I/O 更深入的内容进行介绍。
当我们通过 io_getevents 函数获得了io操作的结果后,我们需要找到与这个IO相关联的应用逻辑实体,比如这个读IO是由哪个任务发起的,然后把读取到的数据交给这个任务,继续进行后续的数据处理。怎么实现关联呢?
我们回顾一下 io_event 结构的成员:
struct io_event {
PADDEDptr(void *data, __pad1); PADDEDptr(struct iocb *obj, __pad2); PADDEDul(res, __pad3); PADDEDul(res2, __pad4);};
其中 void* data 就是解决这类问题的。这个值是从 io_submit 提交的iocb结构中复制的。再看一下 iocb 结构:
struct iocb {
PADDEDptr(void *data, __pad1); /* Return in the io completion event */ PADDED(unsigned key, __pad2); /* For use in identifying io requests */ short aio_lio_opcode; // 请求类型,如:IOCB_CMD_PREAD代表读、IOCB_CMD_PWRITE代表等 short aio_reqprio; // 请求优先级 int aio_fildes; // io操作的fd union {
struct io_iocb_common c; struct io_iocb_vector v; struct io_iocb_poll poll; struct io_iocb_sockaddr saddr; } u;};
struct iocb中的 void* data, 由应用程序来设置,通过io_submit 提交给内核。io_getevents 函数获取io结果,返回的io_event 结构中的v