zoukankan      html  css  js  c++  java
  • Httpd服务进阶知识-调用操作系统的Sendfile机制

             Httpd服务进阶知识-调用操作系统的Sendfile机制

                                                    作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

    一.不用 sendfile 的传统网络传输过程

      read(file, tmp_buf, len)
      write(socket, tmp_buf, len)
    
      硬盘 >> kernel buffer >> user buffer >> kernel socket buffer >> 协议栈
    
      一般网络应用通过读硬盘数据,写数据到 socket 来完成网络传输,底层执行过程:
        (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次拷贝,如能减少切换次数和拷贝次数将会有效提升性能

    二.用 sendfile() 来进行网络传输的过程

      sendfile(socket, file, len);
    
      硬盘 >> kernel buffer (快速拷贝到kernel socket buffer) >> 协议栈
      
      在kernel 2.0+ 版本中,系统调用 sendfile() 就是用来简化上面步骤提升性能的。sendfile() 不但能减少切换次数而且还能减少拷贝次数 
        (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里
  • 相关阅读:
    2017光棍节新生训练赛
    javascript模块化编程(二):AMD规范
    javascript模块化编程(一):模块的写法
    CommonJS Promises/A规范
    javascript面向对象(三):非构造函数的继承
    javascript面向对象(二):构造函数的继承
    javascript面向对象(一):封装
    this用法(ryf)
    javascript继承机制的设计思想(ryf)
    XMLHttpRequest对象用法
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/12013894.html
Copyright © 2011-2022 走看看