原文:https://blog.csdn.net/zhusixun/article/details/81702380

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhusixun/article/details/81702380
那么sendfile是什么东西,他是怎么影响性能的… …  sendfile实际上是 Linux2.0+以后的推出的一个系统调用,web服务器可以通过调整自身的配置来决定是否利用 sendfile这个系统调用。先来看一下不用 sendfile的传统网络传输过程:

read(file,tmp_buf, len);

write(socket,tmp_buf, len);

硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >>协议栈

标题
一个基于socket的服务,首先读硬盘数据,然后写数据到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 ,然后 DMA 从 kernel buffer拷贝数据到协议栈。

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

再来看一下用 sendfile()来进行网络传输的过程:

sendfile(socket,file, len);

硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈

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

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

简单说,sendfile是个比 read 和 write 更高性能的系统接口, 不过需要注意的是,sendfile 是将 in_fd 的内容发送到 out_fd 。而 in_fd 不能是 socket , 也就是只能文件句柄。 所以当 Nginx 是一个静态文件服务器的时候,开启 SENDFILE 配置项能大大提高 Nginx 的性能。 但是当 Nginx 是作为一个反向代理来使用的时候,SENDFILE 则没什么用了,因为 Nginx 是反向代理的时候。 in_fd 就不是文件句柄而是 socket,此时就不符合 sendfile 函数的参数要求了。

最新文章

  1. 电脑只有网页打不开,QQ和其他软件都能用
  2. 关于webrtc视频会议的解决方案
  3. NSString,NSArray,NSNumber等类的继承问题
  4. ./upload/source/class/class_core.php
  5. PAT/进制转换习题集
  6. Linux下的应用程序性能分析 总结
  7. css2----实现三角形和带角框
  8. [JBoss] - 环境搭建
  9. URAL 1227 Rally Championship(树的直径)(无向图判环)
  10. GL_GL系列 - 会计期间管理分析(案例)
  11. Netty4.x中文教程系列(一) Hello World !
  12. 查看sqlserver数据库的端口号
  13. 从 http 升级到 https 过程中遇到的一些问题
  14. ORACLE - 系统参数调整
  15. C语言程序设计基础-第1周作业-初步
  16. Spark的优势
  17. HTTP协议学习笔记---HTTP持久连接和如何正确地关闭HTTP连接
  18. Android - Builder模式
  19. virtualbox+vagrant学习-3-Vagrant Share-5-Security
  20. CF400C/[思维题]

热门文章

  1. Docker 0x03:Install Docker
  2. Linux运维技术之讲解RAID
  3. Docker版zabbix
  4. Cobbler--自动化部署
  5. nginx centos7 出现403 403 Forbidden
  6. Nuxt 知识点
  7. sublime中文解决
  8. can总线学习网上资料汇总
  9. React.js 小书
  10. 使用google autoservice 自动生成java spi 描述文件