什么是零拷贝?
- 快速理解
快速理解
要想理解零拷贝,首先要了解操作系统的IO流程,因为有内核态和用户态的区别,为了保证安全性和缓存,普通的读写流程如下:
(对于Java程序而言,还会多了一个堆外内存和堆内存之间的copy)
如图:
整体的流程我们分析一下:
1.用户read发起系统调用,由用户态进入内核态,通过DMA技术将磁盘中的数据copy到内核缓冲区中;
2.当DMA完成工作后,会发起一个中断,通知CPU数据拷贝完成,然后CPU再将内核态中的数据copy到用户态中;
3.由内核唤醒对应线程,同时将用户态的数据返回给该线程空间;
4.用户态线程进行业务处理;
5.当服务器对请求进行响应的时候,会发起系统调用,由内核将用户态的数据copy到内核态中;
6.复制完毕以后,再由网络适配器通过DMA技术将内核态缓冲区中的数据copy到网卡中,完成以后,内核态会返回到用户态;
7.最后由网卡将数据发送出去。
在这个整个过程中,如果不考虑用户态的内存拷贝和物理设备到驱动的数据拷贝,我们会发现,这其中会涉及4次数据拷贝。同时也会涉及到4次进程上下文的切换。所谓的零拷贝,作用就是通过各种方式,在特殊情况下,减少数据拷贝的次数 / 减少CPU参与数据拷贝的次数。
常见的零拷贝方式有mmap、sendfile、dma、directl/O等等。