目前,我正在尝试了解 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
: 此功能也可用于反向。但根据内核源代码中的注释,数据将被复制。read
: 我可以想象,如果内存正确对齐,这个函数会产生一些魔力,但我对此表示怀疑。mmap
: 在管道上不可能。但是是否有某种虚拟文件可以代替使用,即splice
虚拟文件的内存页和mmap
它?- ... ?
根本不可能vmsplice
吗?