1、传统的IO模型:4次拷贝和3次状态切换
案例说明:通过套接字发送一份文件,用户没有其他操作
4次拷贝分别是:DMA拷贝(将文件从硬盘读取到内核空间)–>CPU拷贝(将内核空间中的数据拷贝到用户空间中)–>CPU拷贝(将用户空间中的数据拷贝到socket buffer中)–>DMA拷贝(socket缓冲区中的数据拷贝到TCP/IP协议栈中进行数据的封装)
3次切换分别是:应用程序需要发送数据那么就需要从1用户态切换到内核态,内核态便将硬盘中的数据加载到内核空间中,然后再从2内核态切换到用户态将内核空间中的数据拷贝到用户空间中,期间用户可以修改数据,最后再从3用户态切换到内核态将用户空间中的数据拷贝到socket缓冲区中。
备注:socket缓冲区是用户用来发送和接收信息的地方
2、mmap(内存映射优化)
1)mmap是通过内存映射,将文件映射到内核空间中,同时用户空间可以共享内核空间中的数据,这样,在进行网络传输时,就可以减少内核空间到用户空间的拷贝次数,因此mmap的优化性能是3次拷贝3次切换
2)mmap示意图
3、sendFile优化
1)在Linux2.1版本中,提供了sendFile函数,其基本原理是数据不需要经过用户态,直接从内核空间进入到socket 缓冲区中,由于与用户态完全无关,就减少了一次上下文切换
2)示意图
注意:零拷贝不是没有拷贝,而是没有CPU拷贝