【发布时间】:2014-01-12 18:13:56
【问题描述】:
我知道 splice() 是为零拷贝而设计的,并使用 Linux 内核管道缓冲区来实现这一点。例如,如果我想将数据从一个文件描述符(fp1)复制到另一个文件描述符(fp2),则不需要从“内核空间->用户空间->内核空间”复制数据。相反,它只是在内核空间中复制数据,流程将类似于“fp1 -> pipe_read -> pipe_write -> fp2”。 我的问题是剂量内核需要在“fp1 -> pipe_read”和“pipe_write -> fp2”之间复制数据?
维基百科说:
Ideally, splice and vmsplice work by remapping pages and do not actually copy any data,
which may improve I/O performance. As linear addresses do not necessarily correspond to
contiguous physical addresses, this may not be possible in all cases and on all hardware
combinations.
我已经为我的问题追踪了kernel source(3.12),我发现“fp1->write_pipe”之间的流程,最后它会在fs/splice.c中调用kernel_readv(),然后调用“do_readv_writev()”,最后称为“aio_write()”
558 static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
559 unsigned long vlen, loff_t offset)
//*vec would point to struct page which belong to pipe
“read_pipe -> fp2”之间的流程最后会调用“__kernel_write()”,然后调用“fp2->f_op->write()”
430 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
//*buf is the pipe buffer
而且我认为“aio_write()”和“file->f_op_write()”都会执行真正的数据复制,那么 splice() 真的执行零复制吗?
【问题讨论】:
-
参考Ans
-
感谢您的回复,但如果 fp 和管道之间存在复制,链接仍然无法响应
标签: c linux linux-kernel