目前,我正在尝试了解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。