54

似乎明白了什么:

POSIX AIOAPI 是原型的<aio.h>,您将程序与 librt(-lrt) 链接,而其中的libaioAPI<libaio.h>和您的程序与 libaio (-laio) 链接。

我无法弄清楚:

1.内核对这两种方法的处理方式不同吗?

2.O_DIRECT使用它们中的任何一个都必须使用标志吗?

本文所述,libaio 在不O_DIRECT使用. 的情况下也能正常工作libaio。好吧,明白了,但是:

根据 R.Love 的Linux System Programming一书,Linux在使用.没有标志打开的文件没有问题。O_DIRECTaio_writeO_DIRECT

4

1 回答 1

74

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

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

  1. 它适用于任何文件系统
  2. 它(基本上)适用于任何操作系统(请记住,gnu 的 libc 是可移植的)
  3. 它适用于启用缓冲的文件(即没有设置 O_DIRECT 标志)

主要缺点是您的队列深度(即您在实践中可以拥有的未完成操作的数量)受到您选择拥有的线程数量的限制,这也意味着一个磁盘上的慢操作可能会阻塞一个操作不同的磁盘。它还会影响内核和磁盘调度程序看到哪些 I/O(或多少)。

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

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

于 2012-01-08T23:21:27.317 回答