零拷贝的零指的是省去内核到用户空间的cpu拷贝(省去了拷贝而且不受用户缓冲区的限制,那么拷贝次数也就少一些)
    最普通的网络数据包括这几个部分:read和write系统调用,page cache和socket缓冲区
    数据要先从磁盘DMA到内核缓冲区,再通过read系统调用cpu拷贝到应用程序缓冲区,在write进socket缓冲区,再DMA进网卡,总共涉及了4次拷贝和4次用户态内核态切换
    image.png
    主要有sendfile和mmap+write的方式,sendfile是使用一个函数代替read和write函数,这种方式下数据可以直接从磁盘DMA到达内核缓冲区再DMA到网卡,只需要两次DMA拷贝(怎么做到内核直接到网卡的DMA的,socket缓冲区中记录了文件描述信息fd),2次内核态用户态切换,但是这种方式不经过用户态,也就无法对数据进行压缩再发送
    image.png
    mmap是通过将用户缓冲区和内核缓冲区做一个映射,这样就省去了用户态和内核态的cpu拷贝,但是在内核缓冲区和socket缓冲区之间还是会有一次cpu拷贝
    image.png
    有副作用:
    1. 零拷贝一般没有机会做压缩或加密等;2.大文件做零拷贝会占用大量pagecache 而且后面命中又少,一般用异步IO的方式传输大文件