当前,我正在尝试了解splice/vmsplice的值(value)。关于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完全不可能吗?

    最佳答案

    如R ..所述,您只需要将fd传递给接收进程somehow,另一方面将其用作常规fd。

    编辑:
    实际上,您必须在发送方使用vmsplice()将缓冲区映射到管道,而在接收方使用splice()在管道的另一端。查看示例here

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

    关于c - Linux零拷贝: Transfer memory pages between two processes with vmsplice,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10639559/

    10-11 15:36