您现在的位置是:主页 > 数据库技术 > 数据库技术

Linux零拷贝怎么实现

IDCBT2022-01-13服务器技术人已围观

简介本篇内容介绍了“Linux零拷贝怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读

本篇内容介绍了“Linux零拷贝怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

为了迅速建立起零拷贝的概念,我们拿一个常用的场景进行引入。在写一个服务端程序时(Web Server或者文件服务器),文件下载是一个基本功能。

这时候服务端的任务是:将服务端主机磁盘中的文件不做修改地从已连接的 Socket 发出去。

我们通常用下面的代码完成:

while((n = read(diskfd, buf, BUF_SIZE)) > 0)     write(sockfd, buf , n);

基本操作就是循环的从磁盘读入文件内容到缓冲区,再将缓冲区的内容发送到 Socket。但是由于 Linux 的 I/O 操作默认是缓冲 I/O。

这里面主要使用的也就是 Read 和 Write 两个系统调用,我们并不知道操作系统在其中做了什么。实际上在以上 I/O  操作中,发生了多次的数据拷贝。

当应用程序访问某块数据时,操作系统首先会检查,是不是最近访问过此文件,文件内容是否缓存在内核缓冲区。

如果是,操作系统则直接根据 Read 系统调用提供的 buf 地址,将内核缓冲区的内容拷贝到 buf 所指定的用户空间缓冲区中去。

如果不是,操作系统则首先将磁盘上的数据拷贝的内核缓冲区,这一步目前主要依靠 DMA 来传输,然后再把内核缓冲区上的内容拷贝到用户缓冲区中。

接下来,Write 系统调用再把用户缓冲区的内容拷贝到网络堆栈相关的内核缓冲区中,最后 Socket 再把内核缓冲区的内容发送到网卡上。

说了这么多,不如看图清楚:

数据拷贝

从上图中可以看出,共产生了四次数据拷贝,即使使用了 DMA 来处理了与硬件的通讯,CPU 仍然需要处理两次数据拷贝。

与此同时,在用户态与内核态也发生了多次上下文切换,无疑也加重了 CPU 负担。

在此过程中,我们没有对文件内容做任何修改,那么在内核空间和用户空间来回拷贝数据无疑就是一种浪费,而零拷贝主要就是为了解决这种低效性。

什么是零拷贝技术(zero-copy)?

零拷贝主要的任务就是避免 CPU 将数据从一块存储拷贝到另外一块存储。

主要就是利用各种零拷贝技术,避免让 CPU 做大量的数据拷贝任务,减少不必要的拷贝,或者让别的组件来做这一类简单的数据传输任务,让 CPU  解脱出来专注于别的任务。这样就可以让系统资源的利用更加有效。

我们继续回到上文中的例子,我们如何减少数据拷贝的次数呢?一个很明显的着力点就是减少数据在内核空间和用户空间来回拷贝,这也引入了零拷贝的一个类型:让数据传输不需要经过  user space。

标签:

很赞哦! ()

本栏推荐