【问题标题】:Is there an asynchronous version of sendfile in Linux?Linux 中有异步版本的 sendfile 吗?
【发布时间】:2018-06-10 12:39:00
【问题描述】:

io_getevents 通知机制乍一看似乎很强大,所以我想要一些可以与它一起使用的东西。我只是还找不到任何东西。在 Windows 上,这很简单:只有TransmitFile,如果你想要的话,它可以异步工作(重叠)和一些通知机制(IOCP、事件)。 Linux 上必须有一些等价物,对吧?或者,将我的问题放在某种背景下,我将如何在 Linux 上创建高效的文件服务器?

【问题讨论】:

  • 如果套接字是非阻塞的,sendfile 也不会(它将报告计划在套接字的“缓冲区”中发送多少数据)。您将需要轮询套接字以查看何时可以继续 sendfile 操作(请参阅 epoll)...或者更好的是,使用为您执行此操作的库。
  • @Myst Mh,当我想到异步 I/O 时,我想到了可以在任意时间点开始并在完成时收到通知的操作。使用 epoll+sendfile,我首先必须等到发送缓冲区可用,调用 sendfile 它将一些数据复制到所述缓冲区(同步!),冲洗并重复。
  • 另外,我读到 sendfile 可能会在与非阻塞套接字一起使用时阻塞,并且可以使用readahead 解决这个问题:brad.livejournal.com/2228488.html 这引入了更复杂的应用程序设计和更多延迟因为在实际工作之前需要大量的上下文切换。我真的不觉得整个“非阻塞”方法令人满意。
  • sendfile 确实不是 asio,但它确实将数据同步复制到套接字的缓冲区(这就是为什么将套接字设置为非阻塞)...实际上,它甚至不复制数据(这是优化的一部分)。据我记得,数据是直接从文件缓冲区打包出来的。
  • @Myst 好的,但是 sendfile 文档非常具有误导性。它明确表示“如果传输成功,则返回写入 out_fd 的字节数。”此外,非阻塞发送/接收 必须 同步复制,没有其他办法。但这不是重点。例如,我想一次在飞行中进行多个发送操作。我认为使用非阻塞套接字+epoll 是不可能的,对吧?使用实际的异步 I/O,我可以将一些标头排队,然后是实际的文件数据。操作系统可以在及时预取文件数据的同时开始发送我的标头。

标签: linux sockets asynchronous sendfile aio


【解决方案1】:

唉,在 Linux 上没有什么容易的事,而且在错误的情况下几乎任何事情都会阻塞 (even io_submit)。回答您的问题(在标题和正文中):

他们是休息时间...

未来(2020+)解决方案

有一个建议是,一些未来的 Linux 内核(晚于 5.5,在撰写本文时已经达到 5.5-rc7)基本上可以执行asynchronous sendfile via io_uring if io_uring gains support for splice()...

【讨论】:

  • 您链接的博客文章似乎建议卸载用户空间线程池中的阻塞操作,这与 arvid 对 libtorrent in 2012 所做的事情相同,因为缺乏更好的替代方案。这正是我想不惜一切代价避免的,以支持一些更高效的 API。我只是希望 Linux 能在 6 年多的时间里有所改进。我的意思是,如果 FreeBSD 能做到这一点,为什么 Linux 不能做到呢?两者都是 POSIX,所以我觉得他们有相似的障碍。
  • 我还希望io_submit 仅在极端情况下阻塞,例如 I/O 请求队列或完成队列填充。我的意思是在这种情况下,你真的确实必须等待事情完成。
  • @purefanatic 缺乏一个伟大的普遍异步 I/O 框架只是 Linux 中的一个缺陷——流行并不意味着你总是在每个类别中都是最好的。 POSIX 从未强制要求使用异步框架,因此这与此正交。 io_submit 可以在您进行缓冲读取时阻塞,该读取未缓存,不是那么奇特或极端。
  • 感谢io_submit 的参考!我认为 POSIX 从不强制要求适当的异步框架是 Linux 在设计时也没有考虑到异步 I/O 的确切原因之一。这就是我称之为障碍的原因。
  • @purefanatic 不客气。好的修正时间-我应该说得更仔细。 POSIX 确实指定了一组 AIO 操作(请参阅 pubs.opengroup.org/onlinepubs/9699919799/basedefs/aio.h.html )但是 a)它是可选的 b)在 Linux 上它是 glibc 使用线程池实现这些功能 c)POSIX 中没有 sendfile。我应该说的是,我没有定义适用于大多数现有操作的 POSIX 定义的 AIO 框架,而不是定义一些新的异步操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 2011-05-27
  • 1970-01-01
相关资源
最近更新 更多