Linux上的AIO支持

时间:2011-10-31 16:40:26

标签: c++ c linux aio

有谁知道在哪里可以获得有关最新Linux内核上aio内核支持状态的最新信息?谷歌搜索会显示可能无可救药地过时的网页。

编辑:

更具体地说,我对非文件相关的描述符如管道和套接字感兴趣。网上的东西表明没有支持,这仍然是这样吗?

EDIT2: 我正在寻找的东西类似于Windows OVERLAPPED IO

3 个答案:

答案 0 :(得分:5)

您不需要POSIX AIO(即man aio)异步使用套接字和管道。根据{{​​1}},它甚至不可能。您应该使用非阻止文件描述符以及事件通知界面,例如man 3 aioselect()或{{1} }。 poll()是特定于Linux的,但比前两个版本要好得多。

要在非阻塞模式下使用文件描述符,您必须在每个文件描述符上设置epoll标志:

epoll

文件描述符处于非阻塞模式后,O_NONBLOCKfcntl(fd, F_SETFL, O_NONBLOCK) 等I / O操作将永远不会阻止,但如果是read()write(),则会返回EAGAINEWOULDBLOCK操作无法立即完成。某些更具体的操作,如connect(),必须以非阻塞模式以不同的方式使用;见相关手册页。

为了能够正确使用非阻塞文件descritors,您的应用程序需要event driven。基本上,在main()中,您需要先初始化内容,然后输入事件循环。事件循环重复等待事件(使用事件通知界面,例如epoll_wait()),然后检查发生了哪些事件,并响应它们。

现在,如果您说read(),并且EWOULDBLOCK失败,则将其添加到为了便于阅读而被观看的文件描述符列表中;当事件提供者指出可读性时,请再试一次。

同样,如果您尝试使用write()并且EWOULDBLOCK失败,则可能需要缓冲数据并在指示可写性时再次尝试。

答案 1 :(得分:4)

Linux下有两种种AIO。

一个是kernel-AIO。它是丑陋的,有时根据文档不符合行为(例如,它会在某些条件下同步运行而不能对它做任何事情,并且在某些条件下它不能正确取消飞行中的请求等,等等)。它确实在管道上工作 这些是io_类函数。请注意,您必须与-laio链接,您必须在某些系统(例如Debian / Ubuntu)上单独安装。{/ p>

第二个是纯用户态实现(glibc),它根据需要生成线程来处理请求。它有详细记录,工作得相当好,并且根据文档,它几乎适用于任何文件描述符包括管道。 这些是aio_类函数。我明确建议使用这些,即使它们是“非冷却的用户态实现” - 它们也能很好地工作。

同时使用eventfd作为通知机制,顺便说一句,虽然内核版本在我上次查看时仍未记录(但函数位于标题中)。

或者,正如Ambroz Bizjak指出的那样,完全跳过AIO,因为你所描述的并不是绝对必要的。

修改
另外,由于您使用了“管道”和“套接字”这两个词,您是否知道vmsplicesplice?这些是向套接字/管道发送数据或从套接字/管道发送数据的最有效的函数。不幸的是,这是另一个模糊记录的,难以理解的黑客有着难以捉摸的陷阱。自行承担风险,您已收到警告。

splice允许您将数据从套接字(或任何文件描述符)传输到管道,或者相反。 vmsplice允许您在应用程序空间和管道之间传输数据 具有讽刺意味的是,vmsplice理想地应该完成同样的事情(重映射页面,又称“与VM一起玩”),一个特定的人在2006年作为争论声称所有BSD开发人员都是白痴。

好消息,坏消息是你可以移动多少数据存在“秘密限制”。据我记得它是64kB(但可以在/ proc中的某处配置)。如果你有更多的数据,你必须工作几个块,可能有几个管道缓冲区,一个读取另一个,并在完成后重新使用旧的管道缓冲区。
这就是它变得复杂的地方。如果您浏览讨论Kernel Trap,您会发现即使是Grand Master也不能100%确定在使用多个缓冲区时可以安全地覆盖旧缓冲区。

此外,对于vmsplice 真正工作(即重新映射页面而不是复制),您需要使用“GIFT”标志,至少对我而言,目前还不清楚docs然后变成那种记忆的东西。按照文档中的文档,您需要泄漏内存,因为您永远不会再次触摸它。当然不可能。也许我只是愚蠢。

我最终放弃了这一点,并且刚刚决定使用epoll来准备普通write的准备和非阻塞套接字。这种组合可能不是最优秀的表现者,但它有充分的记录,并且有记录

答案 2 :(得分:2)

AIO支持已经包含在linux内核中。这就是the first hit on Google仅为2.4 Linux内核提供补丁的原因。在2.6和3.0中它已经在那里。

如果你签出了Linux内核源代码,那就是fs / aio.c

some documentation in the GNU libc manual,但请注意,所有类型的Linux文件描述符都不能使用aio。大多数the general "how to" documentation的日期大约是2006年,这是合适的,因为当时Linux中的AIO成为头条新闻。

请注意,POSIX.1b和Unix98标准没有改变,所以你能否对这些例子的“过时”性质有所了解?