什么是POSIXasynchronousI / O(AIO)的状态?

网页上散布着各种各样的细节描述POSIX AIO设施的页面。 没有一个是最近的。 目前尚不清楚他们描述的究竟是什么。 例如, 这里提供的Linux内核asynchronousI / O支持的“官方” 网站上说socket不工作,但是Ubuntu 8.04.1工作站上的“aio.h”手册页似乎暗示了它适用于任意文件描述符。 然后还有另一个项目,似乎在图书馆层工作,文档更less。

我想知道:

  • POSIX AIO的目的是什么? 鉴于我能find的一个最明显的实现例子,它不支持套接字,整个事情对我来说似乎很奇怪。 只是用于asynchronous磁盘I / O? 如果是这样,为什么超一般的API? 如果没有,为什么磁盘I / O是第一个被攻击的东西?
  • 哪里可以find完整的 POSIX AIO程序,我可以看看?
  • 有没有人真的使用它,真的吗?
  • 哪些平台支持POSIX AIO? 它们支持哪些部分? 有没有人真的支持<aio.h>似乎承诺的隐含的“对任何FD的任何I / O”?

其他可用的多路复用机制是非常好的,但随机的信息碎片让我感到好奇。

networkingI / O不是AIO的优先事项,因为编写POSIXnetworking服务器的每个人都使用基于事件的非阻塞方法。 老式的Java“数十亿的阻塞线程”的方法糟透了。

磁盘写入I / O已被缓冲,磁盘读取I / O可以使用posix_fadvise等函数预取到缓冲区中。 这使得直接的,无缓冲的磁盘I / O成为AIO的唯一有用的目的。

直接的,无缓冲的I / O对事务数据库来说只是非常有用的,而这些I / O往往会编写自己的线程或进程来pipe理它们的磁盘I / O。

所以,最终,POSIX AIO将处于没有任何实际用途的地位。 不要使用它。

有效地实现socket I / O已经通过kqueue,epoll,IO完成端口等解决了。 做asynchronous文件I / O是一个迟到的angular色(除了窗口的重叠I / O和solaris早期支持POSIX AIO)。

如果您正在寻找套接字I / O,那么最好使用上述机制之一。

AIO的主​​要目的是解决asynchronous磁盘I / O的问题。 这很可能是为什么Mac OS X只支持常规文件的AIO,而不是套接字(因为无论如何kqueue都做得更好)。

写操作通常由内核caching并在稍后刷新。 例如,驱动器的读取头恰好经过要写入块的位置。

但是,对于读取操作,如果您希望内核按优先顺序排列读取命令,则AIO是唯一的select。 这就是为什么内核(理论上)可以比任何用户级应用程序做得更好:

  • 内核可以看到所有的磁盘I / O,而不仅仅是你的应用程序磁盘作业,并且可以在全球范围内对它们进行sorting
  • 内核(可能)知道磁盘读取头在哪里,并且可以以最佳顺序select您传递给它的读取作业,将磁头移动到最短距离
  • 内核可以利用本地命令队列来进一步优化读取操作
  • 您可以使用lio_listio()而不是readv()对每个系统调用发出更多的读取操作,特别是如果您的读取不是(逻辑上)连续的,则会节省一点系统调用开销。
  • AIO的程序可能会稍微简单一些,因为您不需要额外的线程来阻止读取或写入调用。

也就是说,posix AIO有一个相当尴尬的界面,例如:

  • 事件callback的唯一有效和良好支持的意思是通过信号,这使得很难在库中使用,因为这意味着使用来自过程全局信号名称空间的信号编号。 如果您的操作系统不支持实时信号,那么也意味着您必须遍历所有未完成的请求,以确定哪一个实际完成(例如Mac OS X,而不是Linux)。 在multithreading环境中捕捉信号也会造成一些棘手的限制。 您通常可以不对信号处理程序中的事件做出反应,但是您必须提高信号,写入pipe道或使用signalfd()(在Linux上)。
  • lio_suspend()与select()具有相同的问题,它不能很好地扩展作业数量。
  • lio_listio(),实现的作业数量相当有限,你可以通过,并且以便携的方式find这个限制并不是微不足道的。 您必须调用可能会失败的sysconf(_SC_AIO_LISTIO_MAX),在这种情况下,您可以使用AIO_LISTIO_MAX定义(不一定定义),但是可以使用2(定义为保证支持)。

至于使用posix AIO的实际应用,你可以看看lighttpd(lighty),它在引入支持时也发布了一个性能testing 。

现在大多数posix平台都支持posix AIO(Linux,BSD,Solaris,AIX,tru64)。 Windows通过重叠的文件I / O支持它。 我的理解是,只有Solaris,Windows和Linux才真正支持asynchronous。 将I / O文件一直下载到驱动程序,而其他操作系统模拟asynchronous。 带有内核线程的I / O。 Linux是个例外,它在glibc中的posix AIO实现模仿用户级线程的asynchronous操作,而它的本地asynchronousI / O接口(io_submit()等)是真正asynchronous的,直到驱动程序,假设驱动程序支持它。

我认为在不支持任何fd的posix AIO的操作系统中是相当常见的,但将其限制为常规文件。

一个libtorrent开发者提供了这个报告: http : //blog.libtorrent.org/2012/10/asynchronous-disk-io/

有一个aio_write – 用glibc实现; 首先调用aio_read或aio_write函数产生许多用户模式线程,aio_write或aio_read将请求发送到该线程,线程执行pread / pwrite,并在完成时将答案回发给阻止的调用线程。

这也是'真正的'aio – 由内核级别支持(需要libaio,请参阅io_submit调用http://linux.die.net/man/2/io_submit ); 也需要O_DIRECT(也可能不被所有的文件系统支持,但主要的支持它)

看这里:

http://lse.sourceforge.net/io/aio.html

http://linux.die.net/man/2/io_submit

Linux上的POSIX AIO和libaio的区别?