Linux上POSIX AIO和libaio之间的区别?

Linux上POSIX AIO和libaio之间的区别?,linux,asynchronous,io,linux-kernel,aio,Linux,Asynchronous,Io,Linux Kernel,Aio,我似乎明白: POSIX AIOAPI是在中原型化的,在使用libaio时,libaio在没有O_DIRECT的情况下可以正常工作。好的,理解了,但是: 根据R.Love的Linux系统编程书,Linux仅在使用O_DIRECT打开时才支持常规文件上的aio(我假设是POSIX aio)。但我编写了一个小程序(使用aio.h,与-lrt链接)在不使用O\u DIRECT标志打开的文件上调用aio\u write不会出现问题。在linux上,这两种aio实现是根本不同的 POSIXAIO是一个用户

我似乎明白:

POSIX AIO
API是在
中原型化的,在使用
libaio
时,libaio在没有
O_DIRECT
的情况下可以正常工作。好的,理解了,但是:


根据R.Love的Linux系统编程书,Linux仅在使用
O_DIRECT
打开时才支持常规文件上的aio(我假设是POSIX aio)。但我编写了一个小程序(使用aio.h,与-lrt链接)在不使用
O\u DIRECT
标志打开的文件上调用
aio\u write
不会出现问题。

在linux上,这两种aio实现是根本不同的

POSIXAIO是一个用户级实现,它在多个线程中执行正常的阻塞I/O,因此产生了I/O异步的错觉。这样做的主要原因是:

  • 它适用于任何文件系统
  • 它(基本上)可以在任何操作系统上工作(请记住gnu的libc是可移植的)
  • 它适用于启用缓冲的文件(即,未设置O_直接标志)
  • 主要缺点是队列深度(即,在实践中可以执行的未完成操作的数量)受您选择的线程数量的限制,这也意味着一个磁盘上的慢速操作可能会阻止一个操作进入另一个磁盘。它还影响内核和磁盘调度器看到的I/O(或数量)

    内核AIO(即io_submit()等)是对异步i/O操作的内核支持,其中io请求实际上在内核中排队,按您拥有的任何磁盘调度器排序,可能其中一些请求作为异步操作(使用TCQ或NCQ)被转发(以某种程度上人们希望的最佳顺序)到实际磁盘。这种方法的主要限制是,并非所有文件系统都能很好地工作,或者根本不能使用异步I/O(并且可能会退回到阻塞语义),文件必须使用O_DIRECT打开,而O_DIRECT对I/O请求有很多其他限制。如果您无法使用O_DIRECT打开文件,它可能仍然“有效”,例如您可以获取正确的数据,但它可能不是异步完成的,而是退回到阻塞语义


    还要记住,io_submit()在某些情况下实际上会在磁盘上阻塞。

    谢谢你的回答。因此对于POSIX AIO,O_DIRECT不是强制性的,但是对于kerenel AIO,它是(确保没有回退发生)?这似乎与书中提到的内容相矛盾。在内核代码中,VFS具有这些aio_读/写函数,这些函数由aio_读/写系统调用(即POXIS aio而非内核aio)调用(?)。没有aio_*系统调用()。您在vfs中看到的aio_*函数可能是内核aio的一部分。用户级aio_*函数不将1:1映射到系统调用。@Arvid请详细说明io_submit()在何种情况下被阻塞?(您有时提到它可能会阻塞磁盘)我的理解是,基本上保证块设备层不会阻塞。如果您只关心访问原始磁盘,那就没事了。但是,文件系统的实现并没有假定有人可能希望异步使用它们。我测试了ext4、reiser和xfs。iirc,ext4是阻塞最多的一个,但它也是完成基准测试最快的一个。搜索LinuxAIO邮件列表会给你很多点击率。这是我的建议:这里有一个非详尽的列表,列出了使
    io\u submit()
    阻塞的内容。。。