【发布时间】:2015-07-02 03:51:51
【问题描述】:
我是通过libaio使用Linux kernel AIO,在上一个读操作完成之前,我必须提交下一个读操作。问题是io_submit() 阻塞了一段时间,我可以从间隔中推断出,它等待上一个操作完成。
我知道我可以用一个 io_submit() 将多个操作排入队列,但这对我来说不是一个选项,因为我不知道下一个读取操作到底会如何,因为已经到了提交第一个。
它是只对我有用,还是对所有人有用?在第二种情况下,请问我是在寻找可行的方法,还是必须回退到线程模型?
【问题讨论】:
-
io_submit会在奇怪的、不可预测的条件下阻塞(这就是我不使用它的原因)。我曾经四处询问并得到类似“当然,它必须以这种方式工作,有一个有限大小的请求队列”的答案。发生这种情况,例如做一个大的请求可能会被分解成几个较小的请求,所以......队列已满并阻塞。线程化 glibc 异步 I/O 实现效果更好,但要注意它会按需生成线程(如果不能接受,请使用您自己的工作池)。 -
还要注意,如果不关闭缓冲,无论如何内核aio都会同步运行。一个允许缓冲异步 I/O 的补丁(由某个印度人开发)已经存在了十年左右,但基于“没人需要”而被拒绝。
-
在我使用它时,我看到它阻塞了几十微秒,偶尔会在 100-200us 范围内出现短暂的现象,但没有比它更高的了。尽管如此,将它放在它自己的线程中就足够了。如果您的阻塞时间超过此时间,请确保您使用 O_DIRECT 打开并且您使用的是 512 字节对齐的内存缓冲区(和长度)。此外,如果您对文件系统上的文件执行此操作,请确保文件系统支持它。这很棘手!
-
我正在使用支持它的 ext4。您是否尝试在第一个操作未完成时执行第二个 io_submit()?
-
两年后我再次偶然发现了这一点,并注意到提到了“ext4”。请注意,ext4 根本不真的 支持 aio(或者相反,aio 不支持 ext4)。即使您“正确”地做所有事情(
O_DIRECT,这是一个主要的反优化和对齐读取),您仍然可能有io_submit块。如果出于某种原因需要读取文件系统元数据,这将在io_submit内阻塞,而您不走运。可悲的是,阻塞并等待一次搜索与等待传输几兆字节大致相同,因此这使得 aio 有点毫无意义。