原文地址:http://www.vpsee.com/2009/07/linux-sendfile-improve-performance/

现在流行的 web 服务器里面都提供 sendfile 选项用来提高服务器性能,那到底 sendfile 是什么,怎么影响性能的呢?sendfile 实际上是 Linux 2.0+ 以后的推出的一个系统调用,web 服务器可以通过调整自身的配置来决定是否利用 sendfile 这个系统调用。先来看一下不用 sendfile 的传统网络传输过程:

read(file, tmp_buf, len);
write(socket, tmp_buf, len);

硬盘 >> 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性能的原因。(参见:64MB VPS 上优化Nginx)

性能测试参考文章地址:

http://blog.csdn.net/crazyguang/archive/2008/05/09/2423708.aspx

sendfile优化文件拷贝相关推荐

  1. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库头文件到 Android 工程中 | 配置 CMakeLists.txt 构建脚本 )

    文章目录 一.拷贝 p7zip 源码中的头文件到 Android Studio 项目中 二.配置 CMakeLists.txt 构建脚本 1.导入动态库 2.导入头文件 三.完整 CMakeLists ...

  2. 【Android 安装包优化】Android 应用中 7zr 可执行程序准备 ( Android Studio 导入可执行 7zr 程序 | 从 Assets 资源文件拷贝 7zr 到内置存储 )

    文章目录 一.Android Studio 导入可执行 7zr 程序 二.从 Assets 资源文件拷贝 7zr 到内置存储空间 三.参考资料 一.Android Studio 导入可执行 7zr 程 ...

  3. 【Android 内存优化】libjpeg-turbo 函数库交叉编译与使用 ( 交叉编译脚本编写 | 函数库头文件拷贝 | 构建脚本配置 | Android Studio 测试函数库 )

    文章目录 一.交叉编译 Shell 脚本参考 二.NDK r16b 版本配置 三.libjpeg-turbo 交叉编译 Shell 脚本 四.执行 libjpeg-turbo 交叉编译 Shell 脚 ...

  4. 【Android 热修复】热修复原理 ( 修复包 Dex 文件准备 | Dex 优化为 Odex | Dex 文件拷贝 | 源码资源 )

    文章目录 一.修复包 Dex 文件准备 二.Odex 优化 三.Dex 文件拷贝 四. 源码资源 一.修复包 Dex 文件准备 异常代码 : 故意写一个异常代码 , 并执行该代码 , 肯定会崩溃 ; ...

  5. 公司服务器文件拷贝痕迹,服务器文件拷贝监控

    服务器文件拷贝监控 内容精选 换一换 在FusionInsight Manager软件安装及使用过程中,针对Tomcat基于开源做了如下功能增强:升级Tomcat版本为官方稳定版本.设置应用程序web ...

  6. 拷贝服务器文件有监控的,服务器文件拷贝监控

    服务器文件拷贝监控 内容精选 换一换 本章节介绍如何将下载的证书安装到Apache服务器上.安装好证书后,您的Web服务器将能支持SSL通信,从而保证您Web服务器的通信安全.如果证书安装过程中遇到问 ...

  7. scp 服务器文件到本地,scp将远程服务器上文件拷贝到本地

    scp将远程服务器上文件拷贝到本地 内容精选 换一换 目前开发的新项目使用的版本控制工具基本用的都是Git,老项目用的还是Svn,网上Git资源也很多,多而杂.一. Git 命令初识在正式介绍Git命 ...

  8. 本地拷贝文件到服务器卡死,本地文件拷贝到服务器

    本地文件拷贝到服务器 内容精选 换一换 您需要将编译后的可执行文件拷贝到目标服务器,并构造相关输入数据,从而运行工程.对于本文档的应用示例,查看$HOME/tools/projects/Custom_ ...

  9. linux c mmap 写文件夹,利用mmap实现文件拷贝功能

    利用mmap实现的一个文件拷贝例子,供大家参考,具体内容如下 /* * gcc -Wall -O3 -o copy_mmap copy_mmap.c */ #include < stdio.h ...

最新文章

  1. springboot 多线程_SpringBoot异步调用@Async
  2. 深度玩转神经网络——基于Keras
  3. C#Windows服务程序安装常见问题解决方法
  4. SELECT INTO 和 replace into SELECT 两种表复制语句
  5. matlab求微分方程同届,Matlab学习——求解微分方程(组)
  6. Teams App如何选择用户
  7. 嵌入式常见笔试题总结(2)
  8. 2020新电商营销白皮书
  9. android 广播 关闭对话框,Android 对话框、信息提示和菜单
  10. k8s核心技术-资源编排(yaml)的介绍---K8S_Google工作笔记0018
  11. 深入理解SpringCloud之Eureka注册过程分析
  12. virtualbox+vagrant快速创建虚拟机
  13. 深入百度蜘蛛IP段详解
  14. 纠删码:定义及常见类型
  15. yolov4 火焰检测 火焰识别 代码 数据集 开源
  16. 如何关闭开启硬件加速
  17. 阿里云-个人建网站从0到精通(二)-快速搭建网站
  18. ionic android n权限,ionic权限问题
  19. 关于类的符号输入过程第三篇
  20. dd命令详细(好文收藏)

热门文章

  1. 图学习02—图神经网络的发展
  2. win10系统要求配置_win10的配置要求是什么?对电脑硬件有什么要求?
  3. 小球自由落体及碰撞反弹
  4. VxWorks 任务使用的学习
  5. 347.前K个高频元素 C++
  6. QString与QByteArray互转
  7. 局域网映射IPV6记录
  8. 史上非常简单、快速的解决Excel导出遇到Excel导出错误
  9. Python中的对象实例化过程 用python解密__new__
  10. [教程] 使用 Chrome 从 Google Drive 进行多线程、断点续传下载