zoukankan      html  css  js  c++  java
  • 零拷贝传输(zero-copy transfer)——sendfile()

      做Web服务器时通常需要将文件传送出去,其中一种方法是通过定义一个buffer每次读取文件发送给接收端。大多数服务器会选择sendfile的方式,nginx实现时就是采用这种方式。对于并发搞得服务器性能上能得到优势。

      

      对于第一种方式需要进入内核两次,分别是读取磁盘文件和写入socket,对于操作系统而言进入内核的开销是不可以忽略的,而sendfile() 采取了所谓的 “zero-copy transfer” 的方式,数据在内核中的时候,就从cbuffer cache 送入 socket buffer中了。花销仅仅一次system call。为了突出显示这两者的区别,我选择发送一个大文件来体现他们之间的效率的差距:

    send() 关键代码:

    (发送文件时定义了一个协议:每次读取文件先将大小发送过去,告诉接收端,这次要接受多大的内容)

    1 for(;;)
    2 {
    3     bzero(buf,sizeof(buf));
    4     size = read(file_fd,buf,sizeof(buf));
    5     if(!size)
    6         break;
    7     send(fd,&size,sizeof(size),0);
    8     send(fd,buf,size,0);
    9 }

    sendfile() 关键代码 :

    sendfile(fd,file,&n,len);

    结果比较:

    1.

    $time a.out
    file
    All done!

    real 0m4.667s
    user 0m0.148s
    sys 0m1.744s

    2.

    $time a.out
    file
    All done.

    real 0m3.113s
    user 0m0.000s
    sys 0m0.020s

      仅仅50M的文件就相差1s了,可以看出主要的差距还是内核时间。服务器选择发送文件时还是sendfile比较靠谱一点。

    最后sendfile的原型:

      ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

      其中in_fd必须是可以进行mmap()操作的,这也就是说接收端不可以用sendfile()接受的,即使前两个参数都是fd,容易给人这样的错觉。

  • 相关阅读:
    项目无法运行iPhone5模拟器
    多线程下载图片,滑动tableView崩溃--资源抢夺问题
    提醒事项 1. 冥想TX 2.下班路上听歌激励自己 3. 不戴眼镜 4. 困难任务拆解
    AutoLayout性能不如frame
    Tunnelblick 覆盖安装失败
    weakSelf 和 strongSelf
    动画
    4/16 近期状态
    知乎live 我的读书经验 总结
    C语言-第23课
  • 原文地址:https://www.cnblogs.com/ittinybird/p/4572799.html
Copyright © 2011-2022 走看看