`
boisterous
  • 浏览: 62868 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类

Linux下提高性能的系统调用sendfile,splice和tee

阅读更多
熟悉Linux内核2.4版本的也许知道:在2.4版的内核中内嵌了一个叫做khttpd的静态网页服务器。当时,可能是效率的因素致使她被添加了进来,至于为什么最新的2.6版内核去掉了这个服务器,我考虑可能是因为Linux内核“只提供机制,
熟悉Linux内核2.4版本的也许知道:在2.4版的内核中内嵌了一个叫做khttpd的静态网页服务器。当时,可能是效率的因素致使她被添加了进来,至于为什么最新的2.6版内核去掉了这个服务器,我考虑可能是因为Linux内核“只提供机制,而不提供策略”,当然安全因素也不能排除在外。

实际上,把网页服务器做进内核也是完全没有必要的,因为Linux内核提供了sendfile这样一个系统调用:

#include <sys/sendfile.h>

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

她能把一个文件从特定部分开始的特定块通过一个socket发送出去,从而避免了多次调用read和write的内核上下文和用户上下文切换的开销,并且由于其内部实现利用了mmap技术,也减少了内存的复制开销。有了她,请问khttpd还有那么必要么?

splice和tee是2.6.17版的Linux内核首次引入的:

#define _GNU_SOURCE
       #include <fcntl.h>

       long splice(int fd_in, off_t *off_in, int fd_out,
                   off_t *off_out, size_t len, unsigned int flags);

#define _GNU_SOURCE
       #include <fcntl.h>

       long tee(int fd_in, int fd_out, size_t len, unsigned int flags);

这两个主要用来减少管道和其他描述符之间传递数据时的read和write系统调用的数目,详细用法请查看man页,其中tee的man页中还给出了采用splice和tee重新实现的一个tee命令作为示例,如有兴趣,可查看一下。

与他们一同引入的还有vmsplice:

#define _GNU_SOURCE
       #include <fcntl.h>
       #include <sys/uio.h>

       long vmsplice(int fd, const struct iovec *iov,
                     unsigned long nr_segs, unsigned int flags);

这个系统调用将用户空间的内存映射到内核空间,从而避免了实际的内存写操作,提高了系统效率。

不过,我并没有觉得splice,tee和vmsplice在实际的代码中很“有用”,倒是觉得如果能去除对管道的限制更好些。因为隧道型的代理服务程序,在连接建立后,剩下的主要任务就是在两个socket之间互相relay数据,如果能把他们splice起来,还是能在一定程度上提高效率的。
分享到:
评论

相关推荐

    Linux高性能服务器编程

    高级IO函数 6.1 pipe函数 6.2 dup函数和dup2函数 6.3 readv函数和writev函数 6.4 sendfile函数 6.5 mmap函数和munmap函数 6.6 splice函数 6.7 tee函数 6.8 fcntl函数 第7章 Linux服务器程序规范 7.1 日志 ...

    splice性能测试

    NULL 博文链接:https://idning.iteye.com/blog/638944

    javascript中不易分清的slice,splice和split三个函数_.docx

    javascript中不易分清的slice,splice和split三个函数_.docx

    浅谈js数组和splice的用法

    下面小编就为大家带来一篇浅谈js数组和splice的用法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    使用接头,cat的实现速度提高了3倍-Linux开发

    cat fcat fcat,fastcat的缩写,是Rust在Linux中使用Linux的splice syscall实现的cat实现。 有了这个小技巧,它的速度是我们基准测试中系统猫的三倍以上。 在此处阅读公告。 cat fcat fcat,fastcat的缩写,是Rust在...

    String-Splice:拼接,但用于字符串而不是数组

    姓名 String :: Splice-拼接,但用于字符串而不是数组 概要 use String::Splice; say ' Perl 6 is awesome ' . & splice ( 0 , 6 , ' Raku '...String :: Splice旨在提供一个简单的接口来对字符串进行切片和切块,其方

    JavaScript中数组slice和splice的对比小结

    今天重温了一下Javascript,看到了数组的方法,其中有两个比较相似的方法——splice和splice,看着很像,就是多了一个p,但是用法却相当不一样。 在使用中,可以通过选择一个具有强语义表达性的 API 来减少混淆的...

    splice-feats解析1

    splice-feats解析1

    js删除数组中的元素delete和splice的区别详解

    例如有一个数组是 :var textArr = [‘a’,’b’,’c’,’d’]; 这时我想删除这个数组中的b元素: 方法一:delete 删除数组 delete textArr[1] 结果为: [“a”,undefined,”c”,”d”]  ...textArr.splice

    JavaScript中splice与slice的区别

    本文给大家分享的是JavaScript中的splice和slice的用法和区别,slice()方法和splice()方法都是原生js中对数组操作的方法,下面我们来详细探讨下

    原生JS中slice()方法和splice()区别

    slice()方法和splice()方法都是原生js中对数组操作的方法。那么他两种有什么区别呢?今天通过本文教程给大家简单介绍下。 slice(),返回一个新的数组,该方法可从已有的数组中返回选定的元素。例如:arrObject(start...

    JavaScript splice()方法详解

    定义和用法splice() 方法用于插入、删除或替换数组的元素。语法arrayObject.splice(index,howmany,element1,…..,elementX)参数 描述index 必需。规定从何处添加/删除元素。该参数是开始插入和(或)删除的数组元素...

    php中array_slice和array_splice函数解析

    本文介绍了php中array_slice和array_splice函数解析,php拆分数组的二个函数(array_slice()、array_splice()),各举一个例子,供大家学习参考。

    splice-string:删除或替换部分字符串,例如Array#splice

    删除或替换部分字符串,例如Array#splice 它可以正确处理带有表情符号的切片字符串。 安装 $ npm install splice-string 用法 import spliceString from 'splice-string' ; spliceString ( 'unicorn' , 3 , 4 , '...

    浅谈js数组splice删除某个元素爬坑

    先来看下几个概念: // splice:返回从原始数组中删除的项(如果没有任何删除,则返回空数组) // 当指定2个参数时,表示删除 // 当指定3个参数,且第2个参数为0时表示插入 // 当指定3个参数,且第2个参数为1时...

    js_arr_splice.html

    js_arr_splice.html

    JavaScript中的splice方法用法详解

    JavaScript中的splice主要用来对js中的数组进行操作,包括删除,添加,替换等。 注意:这种方法会改变原始数组!。 1.删除-用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数) ...

Global site tag (gtag.js) - Google Analytics