sendfile - linux

Kernel 2.1引入sendfile能减少数据复制,优化文件传输性能,apache、nginx、lighttpd、web服务器上都有对应设置。

传统文件传输(读/写)中,需经过多个上下文切换,最终将文件写入socket:

read(file,tmp_buf,len);
write(socket,tmp_buf,len);

传统文件读写过程

1、调用read函数,将文件数据复制到内核缓冲区。

2、read函数从内核缓冲区取回文件数据,复制到用户缓冲区。

3、写函数将文件数据从用户缓冲区,复制到socket相关缓冲区。

4、数据从socket缓冲区复制到协议引擎。

传统网络传输文件过程,经历四次复制操作:

磁盘>内核缓冲区 - >用户缓冲区>socket协议引擎相关缓冲区>

sendfile操作文件过程

sendfile(socket, file, len);

1、调用sendfile,文件数据被复制到内核(kernel)缓冲区。

2、从内核缓冲区复制到socket缓冲区。

3、从socket缓冲区复制到协议引擎。

与传统方式相比,sendfile减少文件的复制过程内核2.4中sendfile更简单。

2.1与2.4的区别

2.4中文件数据被复制到内核缓冲区时,不再将数据复制到与socket缓冲区,只记录socket缓存位置和长度,数据直接发送到DMA协议引擎,减少复制操作,支持的数据不能超过2G。