sendfile为什么比read、writer快

sendfile为什么比read、writer快本文转自: http://www.yanyufly.com/2010/10/22/sendfile为什么比readwrite快/ 在看关于文件IO优化资料时,其中提到了sendfile,man了一下,原理是:由于cp都执行在内核态中,避免用户多次调用的切换以及内存cp,因此性能要高于read()+write().适用于从一个文件读出写到另一个文件(网络Fd也可)#include

大家好,又见面了,我是你们的朋友全栈君。

本文转自: http://www.yanyufly.com/2010/10/22/sendfile为什么比readwrite快/ 

在看关于文件IO优化资料时,其中提到了sendfile,man了一下,原理是: 由于cp都执行在内核态中,避免用户多次调用的切换以及内存cp, 因此性能要高于read()+write(). 适用于从一个文件读出写到另一个文件(网络Fd也可)
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

在网上查到了一个关于sendfile在网络应用的解释,非常好,特列如下:
硬盘 >> kernel buffer >> user buffer >> kernel socket buffer >> 协议栈
一般来说一个网络应用是通过读硬盘数据,然后写数据到 socket 来完成网络传输的。上面2行用代码解释了这一点,不过上面2行简单的代码掩盖了底层的很多操作。来看看底层是怎么执行上面2行代码的:

1、系统调用 read() 产生一个上下文切换:从 user mode 切换到 kernel mode,然后 DMA 执行拷贝,把文件数据从硬盘读到一个 kernel buffer 里。

2、数据从 kernel buffer 拷贝到 user buffer,然后系统调用 read() 返回,这时又产生一个上下文切换:从kernel mode 切换到 user mode。

3、系统调用 write() 产生一个上下文切换:从 user mode 切换到 kernel mode,然后把步骤2读到 user buffer 的数据拷贝到 kernel buffer(数据第2次拷贝到 kernel buffer),不过这次是个不同的 kernel buffer,这个 buffer 和 socket 相关联。

4、系统调用 write() 返回,产生一个上下文切换:从 kernel mode 切换到 user mode(第4次切换了),然后 DMA 从 kernel buffer 拷贝数据到协议栈(第4次拷贝了)。

  上面4个步骤有4次上下文切换,有4次拷贝,我们发现如果能减少切换次数和拷贝次数将会有效提升性能。在kernel 2.0+ 版本中,系统调用 sendfile() 就是用来简化上面步骤提升性能的。sendfile() 不但能减少切换次数而且还能减少拷贝次数。

再来看一下用 sendfile() 来进行网络传输的过程:
sendfile(socket, file, len);
硬盘 >> kernel buffer (快速拷贝到kernel socket buffer) >> 协议栈

1、系统调用 sendfile() 通过 DMA 把硬盘数据拷贝到 kernel buffer,然后数据被 kernel 直接拷贝到另外一个与 socket 相关的 kernel buffer。这里没有 user mode 和 kernel mode 之间的切换,在 kernel 中直接完成了从一个 buffer 到另一个 buffer 的拷贝。

2、DMA 把数据从 kernel buffer 直接拷贝给协议栈,没有切换,也不需要数据从 user mode 拷贝到 kernel mode,因为数据就在 kernel 里。

  步骤减少了,切换减少了,拷贝减少了,自然性能就提升了。这就是为什么说在 Nginx 配置文件里打开 sendfile on 选项能提高 web serve r性能的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144765.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • java学习笔记 head first java

    java学习笔记 head first java文章目录golangtojavaHeadFirstJavagolangtojavagolang工程师,最近开始学习一些javaHeadFirstJavainstanceof相当于断言Dogd=newDog()Objecto=dif(oinstanceofDog){ Dogd=(Dog)o}interface在java和golang中基本一致,java中的interfece是一个100%抽象类,所有函数都是抽象的。必须要用implements显

  • 命令查看Win10等详细激活信息的方法

    命令查看Win10等详细激活信息的方法命令查看Win10等详细激活信息方法:1、slmgr全称:SoftwareLicenseManager2、VBS是基于VisualBasic的脚本语言。VBS的全称是:MicrosoftVisualBasicScriptEdition。(微软公司可视化BASIC脚本版)。Win+R输入:1、slmgr.vbs-dlv显示:最为详尽…

  • Js判断是否联网引入不同js

    Js判断是否联网引入不同js

  • java months between,ORACLE函数MONTHS_BETWEEN

    java months between,ORACLE函数MONTHS_BETWEEN因系统折旧月份是按当月是否满15天来算是否为一个月,故此研究了下MONTHS_BETWEEN已适应折旧的逻辑官网函数说明:MONTHS_BETWEENreturnsnumberofmonthsbetweendatesdate1anddate2.Ifdate1islaterthandate2,thentheresultispositive.Ifdate1…

  • 【SPSS统计分析】SPSS聚类分析:一个案例演示聚类分析全过程(附SPSS 19.0中文版下载)「建议收藏」

    【SPSS统计分析】SPSS聚类分析:一个案例演示聚类分析全过程(附SPSS 19.0中文版下载)「建议收藏」摘要:案例数据源:有20种12盎司啤酒成分和价格的数据,变量包括啤酒名称、热量、钠含量、酒精含量、价格。数据来自《SPSSforWindows统计分析》。目录问题一:选择那些变量进行聚类?——采用“R型聚类”问题二:20中啤酒能分为几类?——采用“Q型聚类”问题三:用于聚类的变量对聚类过程、结果又贡献么,有用么?——采用“单因素方差分析”问题四:聚类结果的解释?——采用”均值比较描述统计“问题一:选择那些变量进行聚类?——采用“R型聚类”1、现在我们…

    2022年10月18日
  • bat自动复制文件命令_批处理命令删除文件夹

    bat自动复制文件命令_批处理命令删除文件夹1建bat文件自动执行复制,删除命令。例1:以下是复制cd.dll文件至windows\system32的bat文件内容:copycd.dll%windir%\system32例2:下面一行是卸载windows\system32目录中的cd.dll,即把上面复制的文件删除:del%windir%\system32\cd.dll例3:删除…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号