splice和sendfile

简介:
在linux2.6.17之后,内核提供了一个splice/tee系统调用,这可以让用户直接操作内核缓冲区了,这个特性特别适合做网络代理,本文简短的说明一下,快下班了。 
在linux2.6.17之后,内核提供了一个splice/tee系统调用,这可以让用户直接操作内核缓冲区了,splice系统调用通过管道 (pipe)可以将文件描述符和管道联系起来,这里的管道实际上是内核借用的一个现成的概念而并不是传统意义上的管道,正如文档中说,它作为队列的作用被 削弱了,它的作用就是一个缓冲区,内核的缓冲区,这样的话,splice就可以将文件描述符数据(传统文件,套接字等等)直接拷贝到这个pipe即拷贝到 内核的缓冲区,或者将内核缓冲区的数据拷贝到文件。既然实现了这个splice,而这个splice看来粒度更加细化了,更加原始了,原来内核中的 sendfile系统调用就没有存在的意义了,完全可以由两次splice来代替,可是还是保留了下来,就是实现机制变化了,完全用splice来实现, 简单点说就是将in文件的数据植入pipe,然后再将pipe的数据植入out文件,两次植入只操作指针并没有实际拷贝数据,最终下来还是在内核拷贝了一 次数据,即从in文件缓冲区到out文件缓冲区,用splice实现sendfile印证了linux中能用现有机制组合实现的机制就不再单独提供一个机 制。当然原来的sendfile是用file_operations接口的read/write来实现的,方案也是不错的,只是耦合性大了点,用 splice实现后,数据操作完全分离了,就是说in文件不再直接和out文件打交道了,而是通过它们的二传手pipe来互相拷贝数据。 

正如文档所说,splice相当于内核缓冲区的read/write,而tee则相当于内核缓冲区的memcpy,这种说法非常直观。看来内核越来越是可 控的了,这种控制不是随便的控制,而是有机的控制,不是为了将权力交给用户,而是为了更好更灵活的提供机制,将一部分机制的实现也交给了用户而已。有了 splice和tee,内核就相当于提供了一个把手或者叫扳子,通过这个把手用户再也不用总把数据拉出来处理完再放回去了,直接操作这个把手就可以了,相 当于一个杠杆。烧锅炉的师傅不用把煤从锅炉弄出来翻完再弄进去,而是直接用火筒就可以了。linux中提供了系统调用接口,这个系统调用接口不也是把手扳 子杠杆吗?从某种意义上说系统调用接口更像是一个代理把门的,他站在固定的地方帮你做事或者帮你把请求传递给里面的人,而不是直接让你自己去做 事,splice就不是简单代理帮你做事或传递请求了,而是真正把工具给你,把扳子,钳子都给你,不过也仅仅让它们这些工具露出一端,另一端还是不让你掌 控,这露出的一端已经足够你用了,你拿着这些把手使劲搅拌吧,成果自然流露。




 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1273416

相关文章
|
1月前
|
前端开发
如何区分slice,splice,split?
如何区分slice,splice,split?
9 0
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
Slice
语言切片(Slice)是一种自然语言处理技术,可以将文本分成多个部分,以便更好地理解和分析文本内容。语言切片通常用于文本分类、情感分析和机器翻译等任务。 使用语言切片,可以指定文本中的哪些部分被视为“重要”或“相关”,从而更好地理解和分析文本。例如,在文本分类任务中,可以将
17 1
|
5月前
|
JavaScript 前端开发
slice()和splice()用法
slice()和splice()用法
21 0
|
6月前
|
前端开发
splice
splice
23 0
|
9月前
|
前端开发
前端数组方法splice
前端数组方法splice
66 0
|
9月前
|
JavaScript 索引
JS数组常用方法(超级详细,含理解) push、pop、unshift、shift、splice、slice、concat、join、revres、indexOf、sort、filter、map
JS数组常用方法(超级详细,含理解) push、pop、unshift、shift、splice、slice、concat、join、revres、indexOf、sort、filter、map
152 0
今天我们来看下数组方法中splice()与slice()的区别
今天我们来看下数组方法中splice()与slice()的区别
|
Dart
Dart 流中的 listen 和 forEach 有什么区别?
stream - Dart 流中的 listen 和 forEach 有什么区别? 如果我有 Stream在 Dart 中,我可以同时使用 listen和 forEach ,但我不明白其中的区别。
109 0
|
缓存
内核中的UDP socket流程(11)——ip_append_data
作者:gfree.wind@gmail.com博客:linuxfocus.blog.chinaunix.net 继续ip_append_data,         if (copy > length)             copy = length;         if (!(rt->dst.
1308 0