【问题标题】:Linux Asynch IO - difference between aio.h and libaio.hLinux 异步 IO - aio.h 和 libaio.h 之间的区别
【发布时间】:2013-11-21 15:18:59
【问题描述】:

我开始研究一种我不知道的新范例,称为 Linux 中的异步 IO。

我的目标是使用异步 IO 目标套接字来编写高性能高效的服务器。原因是我的应用程序是 IO-bound。

在搜索更多信息时,我发现了以下 2 个介绍。

  1. Posix AIO

  2. Linux AIO interface

在异步框架中,我想避免的情况是为我需要异步处理的每个通知创建一个新线程,因为它会杀死我的应用程序。

我的问题如下:

  1. 这两个框架的幕后解决了这个问题吗?

  2. 如果是,您会建议考虑套接字吗?

问候

AFG

【问题讨论】:

    标签: linux sockets asynchronous linux-kernel


    【解决方案1】:

    这些都不是真正用于套接字的。

    POSIX AIO 接口创建使用普通阻塞 IO 的线程。它们与缓冲区缓存一起工作,并且应该原则上甚至可以与套接字一起工作(尽管我承认没有尝试过)。

    Linux 内核 AIO 接口不创建线程来处理请求。它独家在“无缓冲”模式下工作。当心一些不明显的行为,例如在某些情况下提交请求时被阻塞,这是您无法预见或阻止的(除了您的程序表现“奇怪”之外,也不知道)。

    您想要的是非阻塞套接字(非阻塞套接字是“一种异步”)和epoll 以将就绪通知的开销降至最低,并且——如果你能找出几乎不存在的文档—— - splicevmsplice 以减少 IO 开销。使用splice/vmsplice,您可以直接从磁盘 DMA 到内核缓冲区并从那里推送到网络堆栈。或者,您可以直接将页面从应用程序的地址空间移动到内核,然后推送到网络。
    缺点是文档很少(至少可以说),特别是对于 TCP,一些问题仍未解决,例如何时可以安全回收内存。

    【讨论】:

    • POSIX AIO 不一定用线程实现 - 线程实现是在 GLIBC 中实现的可移植 AIO 的一部分,特别是因为在某一时刻(2.5 之前?)Linux 在内核中缺乏 AIO 支持。跨度>
    • 好吧,“POSIX”本身并没有强制要求,这是真的。但是,在 Linux/Glibc 下(问题是关于)它肯定是。听起来很有趣,Glibc 线程实现比内核风格要好得多。
    • 据我所知,内核实现最终从最初的范围缩小,它支持网络通信等。虽然如果想要那种 I/O 风格,不幸的是,*nix 世界与 VMS 和 NT(其 AIO 源自 VMS 的 AIO)相比缺乏。
    • 虽然我可以忍受“没有插座”的事情。我最不喜欢内核实现的是它不可能使用缓冲区缓存,尽管启用此功能的补丁已经存在了 5 年左右(并且因为“不需要”而被拒绝)并且它不是真正的异步。当您提交异步请求时,您最不希望发生的事情是让调用突然无限期阻塞。然而,当有足够多的未完成请求或足够大的请求时,就会发生这种情况。 Glibc POSIX 实现从不阻塞,它应该是这样的。
    【解决方案2】:

    出于网络编程的目的,您将需要基于 事件 的 I/O,通过 select(2) 调用实现(以最基本的形式),并且在某些系统上与 poll()epoll()kpoll()

    POSIX AIO(其中 Linux AIO 是一种实现)不一定适用于套接字(它在 Linux 2.5 代码库中的某个时候确实如此,但我不能确定它是否仍然可行)。

    Unix 上的高性能 socket I/O 以基于事件的方式完成,您在循环中处理传入事件。事件可以是“socket 准备好写入”、“socket 有新数据”等,然后对它们做出反应。

    【讨论】:

      猜你喜欢
      • 2021-10-16
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多