目前,我正在努力了解splice / vmsplice的价值。关于IPC的用例,我在stackoverflow上偶然发现了以下答案:https://stackoverflow.com/a/1350550/1305501
问题:如何使用vmsplice将内存页面从一个进程转移到另一个进程而不复制数据(即零拷贝)?
上述答案声称有可能。但是,它不包含任何源代码。如果我正确理解vmsplice
的文档,如果内存被正确分配和对齐,以下函数将把内存页面转移到管道(内核缓冲区)而不复制。为了便于演示而省略了错误处理。
// 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
:此功能也可用于反向。但根据kernel sources中的评论,数据将被复制。read
:我可以想象,如果内存正确对齐,这个函数会有一些魔力,但我对此表示怀疑。mmap
:管道上不可能。但是有没有可以使用的虚拟文件,即splice
虚拟文件的内存页面和mmap
它? vmsplice
根本不可能吗?