在学习sendfille之前,我们先来了解一下浏览器访问页面时,后台服务器的大致工作流程。

下图是从用户访问某个页面到页面的显示这几秒钟的时间当中,在后台的整个工作过程。

如上图,黑色箭头所示的过程,是传统方式的数据传输:

第一步:当用户请求www.test.com/index.html网页时,nginx服务器通过网卡接收到请求后,系统调用read导致了从用户空间到内核空间的上下文切换,内核再向磁盘发送关于Index.html的请求,DMA模块从磁盘中读取index.html(以下简称为数据)发送到内核缓冲区,完成第一次复制。

第二步:系统调用read返回,导致从内核空间到用户空间的上下文切换,此时数据已存放在用户缓冲区中,完成第二次复制。

第三步:系统调用write导致了从用户空间到内核空间的上下文切换,此时数据存放在了内核空间与socket相关的特定缓冲区中(注意这里要将第一步中的内核缓冲区区分开来),完成第三次复制。

第四步:系统再次调用返回,导致了第四次上下文切换,数据来到了相关协议引擎,完成了第四次复制。再有相关引擎返回给用户浏览器。

这里的复制操作均由DMA模块来执行完成。

了解了这个过程后,我们来看一下sendfile和mmap到底是什么?

sendfile“零拷贝”

它的目的也是提升数据的传输性能

如上图中的红色箭头,sendfile机制实际上就是节省了从内核空间到用户空间,再从用户空间到内核空间这个往返的过程,相比于传统的方式节省了一次数据的复制,提高了访问效率。它的大致步骤是:

第一步:从磁盘到内核空间,完成第一次复制。

第二步:从内核空间到socket buffer(注意这里的缓冲区也要和传统方式中第三部的socket区别开来,可以理解为另一块与socket相关的特定缓冲区),完成第二次复制。

第三步:数据从socket buffer到协议相关引擎,完成第三次复制。

自内核版本号2.1,引进了sendfile2.4之后,sendfile实现了更简单的方式,不同之处在于,文件到达内核缓冲区后,不必再将数据全部复制到socket buffer缓冲区,而只将记录数据位置和长度相关的数据保存到socket buffer,而数据实际由DMA模块直接发送给协议相关引擎,再次降低了复制操作。

mmap内存映射

就是在用户的虚拟地址空间中寻找空闲的一段地址进行对文件的操作,不必再调用read、write系统调用,它的最终目的是将磁盘中的文件映射到用户进程的虚拟地址空间,实现用户进程对文件的直接读写,减少了文件复制的开销,提高了用户的访问效率。

总之,sendfile和mmap的目的就是减少了数据从磁盘到用户过程中的复制操作,使数据传输更加高效,提高用户的访问速率。
————————————————
原文链接:https://blog.csdn.net/keil_wang/article/details/86688271

sendfile“零拷贝”和mmap内存映射的更多相关文章

  1. 【转】Python之mmap内存映射模块(大文本处理)说明

    [转]Python之mmap内存映射模块(大文本处理)说明 背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力 ...

  2. linux mmap 内存映射【转】

    转自:http://blog.csdn.net/xyyangkun/article/details/7830313 [-] mmap vs readwritelseek mmap vs malloc ...

  3. mmap内存映射

    http://blog.csdn.net/kongdefei5000/article/details/70183119 内存映射是个很有用,也很有意思的思想.我们都知道操作系统分为用户态和内核态,用户 ...

  4. linux mmap 内存映射

    mmap() vs read()/write()/lseek() 通过strace统计系统调用的时候,经常可以看到mmap()与mmap2().系统调用mmap()可以将某文件映射至内存(进程空间), ...

  5. Python之mmap内存映射模块(大文本处理)说明

    背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过 ...

  6. mmap内存映射复习

    c语言初学时,比较常见的一个习题就是实现cp. 使用c库实现的cp就不赘述了. 最近工作用到内存映射,就拿来练下手,复习一下mmap的用法. 很简单,将目标文件和源文件映射到内存,然后使用memcpy ...

  7. Linux网络编程--sendfile零拷贝高效率发送文件

    from http://blog.csdn.net/hnlyyk/article/details/50856268 Linux系统使用man sendfile,查看sendfile原型如下: #inc ...

  8. [转载]Linux驱动mmap内存映射

    原文地址:https://www.cnblogs.com/wanghuaijun/p/7624564.html mmap在linux哪里? 什么是mmap? 上图说了,mmap是操作这些设备的一种方法 ...

  9. Linux驱动mmap内存映射

    mmap在linux哪里? 什么是mmap? 上图说了,mmap是操作这些设备的一种方法,所谓操作设备,比如IO端口(点亮一个LED).LCD控制器.磁盘控制器,实际上就是往设备的物理地址读写数据. ...

随机推荐

  1. C#.NET 强大的LINQ

    LINQ 是 Language INtegrated Query 单词的首字母缩写,翻译过来是语言集成查询.它为查询跨各种数据源和格式的数据提供了一致的模型,所以叫集成查询.由于这种查询并没有制造新的 ...

  2. Spring Boot 2.x 多数据源配置之 MyBatis 篇

    场景假设:现有电商业务,商品和库存分别放在不同的库 配置数据库连接 app: datasource: first: driver-class-name: com.mysql.cj.jdbc.Drive ...

  3. 第7.23节 Python使用property函数定义属性简化属性访问的代码实现

    第7.23节 Python使用property函数定义属性简化属性访问的代码实现 一.    背景       在本章前面章节中,我们介绍了类相关的知识,并举例进行了说明,在这些例子中会定义一些形如 ...

  4. PyQt(Python+Qt)学习随笔:布局控件layout的layoutSizeConstraint属性

    在Qt Designer中布局控件有4个,分别是Vertical Layout(垂直布局).Horizontal Layout(水平布局).Grid Layout(网格布局).Form Layout( ...

  5. SSH无密码登陆

    http://blog.chinaunix.net/uid-26284395-id-2949145.html

  6. javascript:void(0)用法和常见问题

    javascript:void(0)的用法 下面的代码创建了一个超级链接,当用户以后不会发生任何事.当用户链接时,void(0) 计算为 0,但 Javascript 上没有任何效果. <a H ...

  7. es6 数组新增方法

    1.Array.from(): 这个函数的作用是将类似数组的对象转化为数组,比如DOM对象 let arrayLike = {      "0":"TangSir&quo ...

  8. 网络QoS的平衡之道——音视频弱网对抗策略介绍

    作者:网易智企云信资深音视频引擎开发工程师 王兴鹤 随着AI和5G的到来,音视频应用将变得越来越广泛,人们对音视频的品质需求也越来越高,视频分辨率已经从高清发展为超高清.VR,视频帧率也已出现60fp ...

  9. 【学习笔记】浅析后缀自动机(SAM)及基础应用

    解决子串相关问题的强大工具 我们知道一个长度为 \(n\) 的字符串中所有的子串数目为 \(O(n^2)\) 个,这很大程度上限制了我们对某些子串相关问题的研究.所以有没有解决方案,使得我们可以在可承 ...

  10. 题解 CF1437G Death DBMS

    这题感觉不是很难,但是既然放在 \(\texttt{EDU}\) 的 \(\texttt{G}\) 题,那么还是写写题解吧. \(\texttt{Solution}\) 首先看到 "子串&q ...