在学习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. Django之数据库--ORM

    一.建立数据库模型类 1.在model里创建模型类.(继承models.Model) from django.db import models # Create your models here. c ...

  2. mongo聚合操作

    1 mongodb的聚合是什么 聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组.过滤等功能,然后经过一系列的处理, ...

  3. moviepy AudioClip的max_volume方法报错ValueError: operands could not be broadcast together with shapes(2,)

    ☞ ░ 前往老猿Python博文目录 ░ 在<moviepy音视频剪辑:AudioClip的max_volume方法报TypeError: bad operand type for abs(): ...

  4. 第十八章、QListView/Model开发

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 QListView理论上可以和所有QAbstractItemModel派生的类如QStri ...

  5. 第十三章、Designer中的按钮Buttons组件详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 Qt Designer中的Buttons部件包括Push Button(常规按钮.一般称按 ...

  6. Thread interrupt() 线程中断的详细说明

    GitHub源码地址 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止 ...

  7. java中的反射(一)

    在之前学java基础时学习过反射,但在因为没有相应的应用场景,所以也是一知半解.最近在学spring的时候发现反射是其中很重要的一部分,所以回顾一下,并看看它在spring中的应用. 目录 一.反射 ...

  8. NET CORE通过NodeService调用js

    在 .NET Framework 时,我们可以通过V8.NET等组件来运行 JavaScript,不过目前我看了好几个开源组件包括V8.NET都还不支持 .NET Core ,我们如何在 .NET C ...

  9. 一文打尽PWM协议、PPM协议、PCM协议、SBUS协议、XBUS协议、DSM协议 | STM32的通用定时器TIM3实现PPM信号输出

    PWM.PPM.PCM.SBUS.XBUS.DSM都是接收机与其他设备通信的协议. 请注意这里不要将遥控器和接收机之间的协议混淆.遥控器和接收机之间会采用某种协议来互相沟通,这些协议往往各个厂牌各自有 ...

  10. MySQL技术内幕InnoDB存储引擎(二)——InnoDB存储引擎

    1.概述 是一个高性能.高可用.高扩展的存储引擎. 2.InnoDB体系架构 InnoDB存储引擎主要由内存池和后台线程构成. 其中,内存池由许多个内存块组成,作用如下: 维护所有进程和线程需要访问的 ...