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

对于第一种方式需要进入内核两次,分别是读取磁盘文件和写入socket,对于操作系统而言进入内核的开销是不可以忽略的,而sendfile() 采取了所谓的 “zero-copy transfer” 的方式,数据在内核中的时候,就从cbuffer cache 送入 socket buffer中了。花销仅仅一次system call。为了突出显示这两者的区别,我选择发送一个大文件来体现他们之间的效率的差距:
send() 关键代码:
(发送文件时定义了一个协议:每次读取文件先将大小发送过去,告诉接收端,这次要接受多大的内容)
for(;;)
{
bzero(buf,sizeof(buf));
size = read(file_fd,buf,sizeof(buf));
if(!size)
break;
send(fd,&size,sizeof(size),);
send(fd,buf,size,);
}
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,容易给人这样的错觉。
零拷贝传输(zero-copy transfer)——sendfile()的更多相关文章
- Netty:Netty中的零拷贝(Zero Copy)
零复制概念: " 零复制"描述了计算机操作,其中CPU不执行将数据从一个存储区复制到另一个存储区的任务.通过网络传输文件时,通常用于节省CPU周期和内存带宽. WIKI的定义中,我 ...
- 对于 Netty ByteBuf 的零拷贝(Zero Copy) 的理解
此文章已同步发布在我的 segmentfault 专栏. 根据 Wiki 对 Zero-copy 的定义: "Zero-copy" describes computer opera ...
- Linux 中的零拷贝技术,第 1 部分
概述 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.本文是本系列文章的第一部分,主要是介绍一些零拷贝技术的相关 ...
- 零拷贝详解 Java NIO学习笔记四(零拷贝详解)
转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...
- [转帖]Linux 中的零拷贝技术,第 1 部分
Linux 中的零拷贝技术,第 1 部分 https://www.ibm.com/developerworks/cn/linux/l-cn-zerocopy1/index.html 引言 传统的 ...
- 【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析
零拷贝Zero-Copy 我们先来看下它的定义: "Zero-copy" describes computer operations in which the CPU does n ...
- Netty中ByteBuf 的零拷贝
转载:https://www.jianshu.com/p/1d1fa2fe1ed9 此文章已同步发布在我的 segmentfault 专栏. 根据 Wiki 对 Zero-copy 的定义: &quo ...
- java的零拷贝机制
转:https://blog.csdn.net/zhouhao88410234/article/details/77574689?fps=1&locationNum=9 为何要懂零拷贝原理?因 ...
- netty如何实现零拷贝
根据 Wiki 对 Zero-copy 的定义: "Zero-copy" describes computer operations in which the CPU does n ...
随机推荐
- java多线程-线程通信
线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 通过共享对象通信 忙等待 wait(),notify()和 notifyAll() 丢失的信号 假唤醒 多线 ...
- .Net中的并行编程-6.常用优化策略
本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略. 一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...
- 基于jQuery的ajax对WebApi和OData的封装
基于jQuery的ajax对WebApi和OData的封装 WebApi 的使用带来了一个显著的特点,对type有一定的要求.一般ajax的type无非就是两种,GET和POST.如果用JSONP来跨 ...
- ThinkPHP3.2 G函数代码及 使用方法
ThinkPHP3.2 G函数代码及 使用方法 代码: // 内存是否可调用 define('MEMORY_LIMIT_ON',function_exists('memory_get_usage')) ...
- 2016年末闲谈iOS开发的未来
移动开发市场潮流涌动,好多人都会问iOS开发的前景这样的问题,今天我就瞎扯一下我眼中的未来,纯主观非理性,爱看看. Swift怎么样 Swift很好,就像你的前女友一样好. 得益于swift的开源,以 ...
- 高性能的JavaScript库---Lodash
上周在仿做Nodejs社区的时候,遇到了lodash这个javascript库,很惭愧,那也是我第一次听说lodash.人嘛,对于新鲜的事物总是会或多或少感到些好奇的,于是就毫不犹豫地去lodash官 ...
- ae开发基础功能
放大.缩小.pan.框选要素(新建命令,建立命令HOOK,赋给当前地图控件): ICommand cmd = new ControlsSelectFeaturesTool(); cmd.OnCreat ...
- ubuntu 搭建开发环境
一. 安装C/C++程序的开发环境 1. sudo apt-get install build-essential //安装主要编译工具 gcc, g++, make 2. sudo apt-get ...
- Android 图片的合成
本文实现在Android下图片的合成 布局设计比较简单: <RelativeLayout xmlns:android="http://schemas.android.com/apk/r ...
- java你可能不知道的事(2)--堆和栈
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...