网页上散布着以不同详细信息描述POSIX AIO设施的页面。它们都不是最近的。目前还不清楚他们究竟在描述什么。例如,“官方”(?)web site for Linux kernel asynchronous I/O support here表示套接字不起作用,但我的Ubuntu 8.04.1工作站上的“aio.h”手册页似乎都暗示它适用于任意文件描述符。然后有another project that seems to work at the library layer甚至更少的文档。
我想知道:
<aio.h>
似乎承诺暗示的“对任何FD的任何I / O”?我可以使用的其他多路复用机制非常好,但随处可见的信息碎片让我很好奇。
答案 0 :(得分:69)
使用kqueue,epoll,IO完成端口等解决了有效执行套接字I / O的问题。做异步文件I / O是一个后来者(除了Windows的重叠I / O和solaris早期支持posix AIO)。
如果您正在寻找套接字I / O,那么最好使用上述机制之一。
因此,AIO的主要目的是解决异步磁盘I / O的问题。这很可能是为什么Mac OS X仅支持常规文件的AIO,而不支持套接字(因为kqueue无论如何都能做得更好)。
写操作通常由内核缓存并在以后刷新。例如,当驱动器的读头碰巧要通过要写入块的位置时。
但是,对于读取操作,如果您希望内核确定优先级并对读取进行排序,那么AIO实际上是唯一的选择。这就是为什么内核可以(理论上)比任何用户级应用程序更好地做到这一点:
也就是说,posix AIO有一个相当尴尬的界面,例如:
对于使用posix AIO的实际应用程序,您可以查看lighttpd(lighty),它在引入支持时也发布了performance measurement。
目前大多数posix平台都支持posix AIO(Linux,BSD,Solaris,AIX,tru64)。 Windows通过其重叠文件I / O支持它。我的理解是只有Solaris,Windows和Linux真正支持异步。文件I / O一直到驱动程序,而其他操作系统模拟异步。内核线程的I / O. Linux是例外,它在glibc中的posix AIO实现模拟用户级线程的异步操作,而其本机异步I / O接口(io_submit()等)真正异步到驱动程序,假设驱动程序支持它
我认为在操作系统中,不支持任何fd的posix AIO,但将其限制为常规文件是相当普遍的。
答案 1 :(得分:25)
网络I / O不是AIO的优先级,因为编写POSIX网络服务器的每个人都使用基于事件的非阻塞方法。旧式的Java“数十亿阻塞线程”方法非常糟糕。
磁盘写入I / O已经缓冲,磁盘读取I / O可以使用posix_fadvise等函数预取到缓冲区中。这使得直接的,无缓冲的磁盘I / O成为AIO唯一有用的目的。
直接,无缓冲的I / O仅对事务数据库非常有用,并且那些人倾向于编写自己的线程或进程来管理其磁盘I / O.
因此,最终使POSIX AIO处于不服务任何有用目的的位置。不要使用它。
答案 2 :(得分:11)
libtorrent开发人员提供了有关此问题的报告:http://blog.libtorrent.org/2012/10/asynchronous-disk-io/
答案 3 :(得分:2)
有一个aio_write - 在glibc中实现;第一次调用aio_read或aio_write函数会生成许多用户模式线程,aio_write或aio_read发出对该线程的请求,该线程会pread / pwrite,当它完成后,答案将被发送回被阻塞的调用线程。
Ther也是真实的&#39; aio - 由内核级别支持(需要libaio,请参阅io_submit调用http://linux.die.net/man/2/io_submit);也需要O_DIRECT(所有文件系统也可能不支持,但主要支持它)
见这里:
http://lse.sourceforge.net/io/aio.html