3

序幕

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

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

更少的代码。更高效。惊人的。

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

我只是想知道...

问题

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

4

2 回答 2

4

我似乎记得这是早期 Linux 2.6 中引入的限制(2.4 没有限制)。

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

于 2009-12-09T22:11:42.020 回答
3

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

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

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

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

于 2009-12-09T22:52:12.837 回答