10

根据本教程,异步磁盘文件 io 可以在 linux 上使用 AIO 轻松实现,至少从编程/api 的角度来看是这样。但是在本教程之前和之后,我阅读了很多帖子和文章,这要么无法完成,要么您应该使用带有补丁的 libevent 和许多其他问题。另一件事是我应该等待信号的循环,但根据本教程,我可以使用回调机制,这显然使 AIO 更易于使用。

现在,我什至不是一个 linux 程序员,我只是想找到一种简单的方法来支持 linux 上的异​​步磁盘文件 io,学习它并将其添加到我个人项目所需的异步磁盘 io 库中。目前,我在 windows 上使用重叠 io,在非 windows 平台上使用 io 工作线程。由于多线程解决方案可能很棘手,我想在 linux 上用 AIO 替换它。

那么,本教程中描述的 AIO 有什么问题?是性能吗?使用 AIO 可以完成的操作是否有限制?

ps 我不在乎代码是否不能移植到其他兼容 POSIX 的平台,只要它适用于主要的 linux 发行版。我只关心常规磁盘文件 io。

谢谢。

4

2 回答 2

14

本教程概述了异步 I/O,并讨论了内核如何支持它。然后继续讨论 posix AIO(这是用于访问异步 I/O 的标准化 API),这意味着在 linux 上使用 posix AIO API 将使您能够访问内核对 AIO 的支持。不是这种情况。

在 linux 上,实际上有两个独立的 AIO 实现:

  1. 内核 AIO 使用 io_submit() 等),仅在内核 2.6(或实际上是 2.5)中受支持,并且可能有向后移植到 2.4 的版本。
  2. posix AIO 这是一个 glibc 特性,本质上与内核无关。它根据用户级线程进行阻塞磁盘 I/O 调用来实现 posix API。

因此,简而言之,如果您已经有一个用于磁盘 I/O 的多线程的通用实现,那么使用它可能比使用 glibc 的实现更好(因为您可能对它有更多的控制权)。

如果您致力于实际使用 io_submit() 系列函数,则可能需要做很多工作来规避对这些函数的限制。

内核 AIO要求您的文件使用 O_DIRECT 打开。这反过来又要求您的所有文件偏移量、读取和写入大小与磁盘上的块对齐。如果您只使用一个大文件,这通常很好,并且您可以使其与操作系统中的页面缓存非常相似。对于以任意偏移量和长度读取和写入任意文件,它会变得混乱。

如果您最终尝试使用内核 AIO,我强烈建议您考虑将一个或多个 eventfds 绑定到您的 iocbs,以便您可以使用 epoll/select 等待完成,而不必阻塞 io_getevents()。

于 2011-12-19T04:53:07.123 回答
3

POSIX AIO 的 Linux 实现会为您执行的每次写入生成一个线程。这通常不好,你最好使用自己的工作线程来进行写入,这样你就可以控制有多少线程在运行。换句话说,坚持你所拥有的,AIO 不会给你买任何东西。

于 2011-12-15T02:01:30.227 回答