• sendfile学习


    参考

    https://zhuanlan.zhihu.com/p/20768200?refer=auxten

    而成本很多时候的体现就是对计算资源的消耗,其中最重要的一个资源就是CPU资源。

    Sendfile(2)在这个时代背景下于2003年前后被加入Linux Kernel,陆续在各大UNIX、Linux、Solaris平台上获得了支持。这个系统内核调用本身被设计出来是用来从磁盘到TCP协议栈拷贝数据用的,但也我们也是可以把它用来做两个文件之间的数据拷贝。

    在Linux Kernel 2.6版本中,这个系统调用的原型是这样的:

    ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
    
    • in_fd 被打开是等待读数据的fd.
    • out_fd 被打开是等待写数据的fd.
    • Offset 是在正式开始读取数据之前应该向前偏移的byte数.
    • count 是需要在两个fd之间“搬移”的数据的byte数.

    参数特别注意的是:in_fd必须是一个支持mmap函数的文件描述符,也就是说必须指向真实文件,不能使socket描述符和管道。

    out_fd必须是一个socket描述符。

    由此可见sendfile几乎是专门为在网络上传输文件而设计的。


    在sendfile(2)出现之前,我们想要把一个文件发送到socket上需要进行如下几个步骤:

    1. 调用read(2)函数,文件数据被copy到内核缓冲区
    2. read(2)函数返回,文件数据从内核缓冲区copy到用户缓冲区
    3. write(2)函数调用,将文件数据从用户缓冲区copy到内核与socket相关的缓冲区。
    4. 数据从socket缓冲区copy到相关协议引擎。
     

    相比sendfile(2),“Read & Write”方式带来的性能损耗主要有两点:

    1. 不必要的内存拷贝。
    2. 系统调用带来的额外的用户态/内核态上下文切换(Context Switch)。

    而我们知道,上下文切换涉及到非常多的CPU、内存堆栈的操作,会让分支预测失败率大增,所以频繁的上线文切换是高性能编程的大忌。类UNIX操作系统里都有一个系统命令vmstat可以展示当前系统的“Context Switch”的量(--system--下的cs列):

     
  • 相关阅读:
    while (cin>>str)退出死循环
    内存溢出(heap corruption detected:)
    二叉树的遍历--递归+非递归(两种)
    直接插入排序(带哨兵和不带哨兵)
    二项队列
    左式堆
    优先队列之二叉堆与d-堆
    centos6.4 安装code::blocks
    结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆
    数据结构与算法分析-开放定址散列表的实现
  • 原文地址:https://www.cnblogs.com/charlesblc/p/6341605.html
Copyright © 2020-2023  润新知