网络I/o编程模型8 IO的零拷贝技术

Posted 健康平安的活着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络I/o编程模型8 IO的零拷贝技术相关的知识,希望对你有一定的参考价值。

一 传统IO模式

1.传统模式:

read:把数据从磁盘读取到内核缓冲区,再拷贝到用户缓冲区

write:先把数据写入到 socket缓冲区,最后写入网卡设备

如下图所示:

2.流程:

1.用户空间的应用程序通过read()函数,向操作系统发起IO调用,上下文从用户态到切换到内核态,然后再通过 DMA 控制器将数据从磁盘文件中读取到内核缓冲区

2.接着CPU将内核空间缓冲区的数据拷贝到用户空间的数据缓冲区,然后read函数调用返回的结果,又会导致上下文从内核态切换到用户态。

3.用户空间的应用程序通过write()函数向操作系统发起IO调用,上下文再次从用户态切换到内核态;接着CPU将数据从用户缓冲区复制到内核空间的 socket 缓冲区(也是内核缓冲区,只不过是给socket使用),然后write函数被系统调用返回,再次触发上下文切换。

4.最后异步传输socket缓冲区的数据到网卡,也就是说write系统调用的返回并不保证数据被传输到网卡。

3.总结:

在传统的数据 IO 模式中,读取一个磁盘文件,并发送到远程端的服务,就共有四次用户空间与内核空间的上下文切换,四次数据复制,包括两次 CPU 数据复制,两次 DMA 数据复制

4.缺点

两次 CPU 数据复制才是最消耗资源和时间的,这个过程还需要内核态和用户态之间的来回切换,而CPU资源十分宝贵,要拷贝大量的数据,还要处理大量的任务,如果能把 CPU 的这两次拷贝给去除掉,既能节省CPU资源,还可以避免内核态和用户态之间的切换。而零拷贝技术就是为了解决这个问题。

二 零拷贝技术

2.1 零拷贝技术

常规的io读写顺序:把数据从磁盘读取到内核缓冲区,再拷贝到用户缓冲区,涉及到共有四次用户空间与内核空间的上下文切换,四次数据复制,包括两次 CPU 数据复制,两次 DMA 数据复制

所谓的零拷贝是在内核空间中直接将磁盘文件复制到网卡中,而不需要经由用户态的应用程序之手。这样就能把 CPU 的这两次拷贝给去除掉,既能节省CPU资源,还可以避免内核态和用户态之间的上下文切换,提高数据传输效率。

2.2 mmap + write 实现的零拷贝

Java IO篇:什么是零拷贝?_张维鹏的博客-CSDN博客_零拷贝

以上是关于网络I/o编程模型8 IO的零拷贝技术的主要内容,如果未能解决你的问题,请参考以下文章

Linux 中的零拷贝技术

IO模型对比:同步异步阻塞非阻塞

何为真正的零拷贝

Go语言中的零拷贝优化,值得大家收藏

Linux 中的零拷贝技术 转

Java IO编程全解——传统的BIO编程