【问题标题】:Is writing to a socket an arbitrary limitation of the sendfile() syscall?写入套接字是 sendfile() 系统调用的任意限制吗?
【发布时间】:2010-12-25 00:31:12
【问题描述】:

前奏

sendfile() 是一个非常有用的系统调用,原因有两个:

首先,它比read()/write()(或recv()/send(),如果您更喜欢那个jive)循环更少
其次,它比上述方法更快(更少的系统调用,实现可以在设备之间复制没有缓冲区等)。

更少的代码。更高效。太棒了。

在 UNIX 中,一切(大部分)都是一个文件。这是柏拉图理论与现实世界实践碰撞的丑陋领域。我知道套接字与驻留在某些设备上的文件根本不同。我还没有通过 Linux/*BSD/Darwin/whatever OS 实现 sendfile() 的源代码来了解为什么这个特定的系统调用仅限于写入套接字(特别是流式套接字)。

我只是想知道...

问题

是什么限制了sendfile() 允许目标文件描述符是套接字以外的东西(如磁盘文件或管道)?

【问题讨论】:

  • 在 2.6.33 及更高版本中,sendfile 的 out_fd 参数可以是任何 fd(不仅仅是套接字)。

标签: unix kernel implementation system-calls sendfile


【解决方案1】:

我好像记得这是早期 Linux 2.6 中引入的一个限制(2.4 没有这个限制)。

从 2.6.17 开始,Linux 有了类似的 splice() 系统调用;更灵活,但效率略低。 Linus 谈到了用 splice() 重新实现 sendfile。见http://kerneltrap.org/node/6505

【讨论】:

    【解决方案2】:

    从根本上说,唯一限制它的是“还没有人编写代码”。

    但是,我认为没有人为您提到的这两种情况编写代码的原因是它们都需要复制数据,这首先消除了使用 sendfile 的大部分优势.

    • 对于文件到文件sendfile,您需要一个副本,因为否则同一页面必须在页面缓存中作为源文件中的干净页面和脏页面目标文件。我不认为页面缓存是为处理这种情况而构建的(当然,如果有足够的动机,这可以改变)。

    • 对于文件到管道sendfile,您需要一个副本,因为目标进程需要获取数据的私有、可写副本。无论如何,对于这种情况的大多数用途,我们已经有了mmap

    【讨论】:

      猜你喜欢
      • 2014-09-01
      • 2012-09-13
      • 2018-12-01
      • 2021-08-17
      • 1970-01-01
      • 2011-02-14
      • 2013-01-03
      • 2014-04-26
      • 2011-07-03
      相关资源
      最近更新 更多