Linux Zero-Copy:使用vmsplice在两个进程之间传输内存页面

目前,我正在尝试了解splice / vmsplice的价值。 关于IPC的使用情况,我偶然发现了以下在计算器上的答案: https : //stackoverflow.com/a/1350550/1305501

问题:如何使用vmsplice将内存页从一个进程转移到另一个进程而不复制数据(即零拷贝)?

上面提到的答案声称这是可能的。 但是,它不包含任何源代码。 如果我正确理解了vmsplice的文档,下面的函数将把内存页面传送到一个pipe道(内核缓冲区)而不复制,如果内存被正确分配和alignment的话。 error handling省略,以便于演示。

 // data is aligned to page boundaries, // and length is a multiple of the page size void transfer_to_pipe(int pipe_out, char* data, size_t length) { size_t offset = 0; while (offset < length) { struct iovec iov { data + offset, length - offset }; offset += vmsplice(pipe_out, &iov, 1, SPLICE_F_GIFT); } } 

但是如何在不复制的情况下从用户空间访问内存页面呢? 显然以下方法不起作用:

  • vmsplice :该function也可用于反向。 但根据内核来源的评论,数据将被复制。
  • read :我可以想象,如果内存正确alignment,这个函数会有一些魔力,但我怀疑它。
  • mmap :不可能在pipe道上。 但是,有没有什么可以使用的虚拟文件,即将内存页面splice到虚拟文件和mmap呢?
  • …?

vmsplice完全vmsplice吗?

正如R ..所提到的,你只需要将fd传递给接收进程就可以了,另一方面可以用它作为正常的fd。

编辑:实际上,您必须在发送端使用vmsplice()将缓冲区映射到管道另一端的接收端的管道和splice()。 在这里看到一个例子。

另一种选择是使用共享的mmap。