在网络传输文件时,涉及到大量的io操作。
发送端:
read函数读取文件到用户缓冲区,先把文件从磁盘拷贝到linux内核(dma来完成,不占用cpu),再从linux内核拷贝到用户缓冲区(cpu来完成),涉及到了两次数据拷贝。
然后把用户缓存区数据使用send发送,cpu再把数据从用户缓存拷贝到socket缓冲区,dma再把linux内核中的数据拷贝到网卡。
总共需要四次拷贝才能把磁盘文件发送出去。
解决办法:
一、使用mmap函数而不是用read,dma把文件拷贝到linux内核后,linux内核和用户缓存区共享linux内核数据,相当于把linux内核数据映射到用户缓存区。
再使用send的时候,cpu把数据从内核拷贝到socket缓冲区,再把数据从socket缓冲区拷贝到网卡(dma)。
只用了三次拷贝,磁盘到内核,内核到网卡。
二、sendfile函数
sendfile和mmap类似,都需要三次拷贝
对于支持网卡支持 sg-dma 技术的情况下, sendfile只会产生两次数据拷贝