Linux上的POSIX AIO和libaio的区别?
我似乎明白:
在<aio.h>
中原型化POSIX AIO
API,并将程序与librt(-lrt)链接起来,而<libaio.h>
的libaio
API和程序与libaio(-laio)链接。
我无法弄清楚的是:
1.内核是否以不同的方式处理这些方法?
2.是否必须使用O_DIRECT
标志来使用它们之一?
正如在这篇文章中提到的 ,当使用libaio
时,libaio可以正常工作,不需要O_DIRECT
。
根据R.Love的“ Linux系统编程”一书的说法,Linux只支持用O_DIRECT
打开, 才支持常规文件上的aio (我认为是POSIX AIO)。但是我写的一个小程序(使用aio.h,与-lrt连接)没有O_DIRECT
标志打开的文件上的aio_write
没有问题。
在Linux上,两个AIO实现是根本不同的。
POSIX AIO是一个用户级别的实现,它在多个线程中执行正常的阻塞I / O,因此给出I / Oasynchronous的错觉。 这样做的主要原因是:
- 它适用于任何文件系统
- 它(基本上)在任何操作系统上工作(请记住,gnu的libc是便携式的)
- 它在启用缓冲的文件上工作(即没有设置O_DIRECT标志)
主要的缺点是你的队列深度(也就是你在实际中可能遇到的未完成的操作的数量)受到你select的线程数量的限制,这也意味着在一个磁盘上缓慢的操作可能会阻止一个操作进入不同的磁盘。 它也影响内核和磁盘调度程序看到哪些I / O(或多less)。
内核AIO(即io_submit()et.al.)是内核对asynchronousI / O操作的支持,其中io请求实际上在内核中排队,按照你有的任何磁盘调度器进行sorting,大概有一些转发按照某种理想的顺序,希望)作为asynchronous操作(使用TCQ或NCQ)到实际的磁盘。 这种方法的主要限制是,并不是所有的文件系统都能够很好的使用asynchronousI / O(可能会回退到阻塞语义),文件必须使用O_DIRECT打开,这个文件带有很多其他的限制I / O请求。 如果你用O_DIRECT打开你的文件失败,它可能仍然是“工作”,因为你得到正确的数据,但它可能不是asynchronous完成,但是回落到阻塞语义。
另外请记住,在某些情况下,io_submit()实际上可以阻塞在磁盘上。