<small id='Ww4gVPkM8'></small> <noframes id='UfiVKsNnSO'>

  • <tfoot id='AltqTL'></tfoot>

      <legend id='jw9Xl'><style id='9sGg4t'><dir id='3Zygb'><q id='WbUyMmYEk'></q></dir></style></legend>
      <i id='ikgwO3EnGT'><tr id='7q1A8k'><dt id='lFSKAaZn'><q id='hrYVmn'><span id='9xDeASt'><b id='tkdq79'><form id='ZkWrRhpu'><ins id='7WPLQ'></ins><ul id='N1piDL6mQq'></ul><sub id='xfTe0G6Or'></sub></form><legend id='SCHzNbQUYe'></legend><bdo id='I8WvsP'><pre id='4CkXvJs'><center id='CNILE'></center></pre></bdo></b><th id='HIor'></th></span></q></dt></tr></i><div id='yzF2qk6a'><tfoot id='WOx3aoQ'></tfoot><dl id='wX3b1o'><fieldset id='npqwFW8x65'></fieldset></dl></div>

          <bdo id='d9zvO'></bdo><ul id='ewkmf'></ul>

          1. <li id='ZiAbwDH6xQ'></li>
            登陆

            章鱼彩票电脑-还不明白零复制(Zero-Copy)?怎样称得上高档程序员

            admin 2019-12-13 234人围观 ,发现0个评论

            概述

            考虑这样一种常用的景象:你需求将静态内容(相似图片、文件)展现给用户。那么这个景象就意味着你需求先将静态内容从磁盘中复制出来放到一个内存buf中,然后将这个buf通过socket传输给用户,从而用户或许静态内容的展现。这看起来再正常不过了,可是实际上这是很低效的流程,咱们把上面的这种景象笼统成下面的进程:

            read(file, tmp_buf, len);
            write(socket, tmp_buf, len);

            首要调用read将静态内容,这儿假设为文件A,读取到tmp_buf, 然后调用write将tmp_buf写入到socket中,如图:

            在这个进程中文件A的阅历了4次copy的进程:

            1. 首要,调用read时,文件A复制到了kernel形式;
            2. 之后,CPU操控将kernel形式数据copy到user形式下;
            3. 调用write时,先将user形式下的内容copy到kernel形式下的socket的buffer中;
            4. 最终将kernel形式下的socket buffer的数据copy到网卡设备中传送;

            从上面的进程能够看出,数据白白从kernel形式到user形式走了一圈,浪费了2次copy(第一次,从kernel形式复制到user形式;第2次从user形式再复制回kernel形式,即上面4次进程的第2和3进程。)。而且上面的进程中kernel和user形式的上下文的切换也是4次。

            走运的是,你能够用一种叫做Zero-Copy的技能来去掉这些无谓的copy。应用程序用Zero-Copy来章鱼彩票电脑-还不明白零复制(Zero-Copy)?怎样称得上高档程序员恳求kernel直接把disk的data传输给socket,而不是通过应用程序传输。Zero-Copy大大提高了应用程序的功能,而且削减了kernel和user形式上下文的切换。

            胪陈

            Zero-Copy技能省去了将操作体系的read buffer复制到程序的buffer,以及从程序buffer复制到socket buffer的进程,直接将read buffer复制到socket buffer. Java NIO中的FileChannal.tr章鱼彩票电脑-还不明白零复制(Zero-Copy)?怎样称得上高档程序员ansferTo()办法便是这样的完成,这个完成是依赖于操作体系底层的sendFile()完成的。

            public void transferTo(long position, long count, WritableByteChannel target);

            他底层的调用时体系调用**sendFi冈本le()**办法:

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

            下图展现了在transferTo()之后的数据流向:

            下图展现了在运用transferTo()之后的上下文切换:

            运用了Zero-Copy技能之后,整个进程如下:

            1. transferTo()办法使得文件A的内容直接复制到一个read buffer(kernel buffer)中;
            2. 然后数据(kernel buffer)复制到socket buffer中。
            3. 最终将socket buffer中的数据复制到网卡设备(protocol engine)中传输;

            这显然是一个巨大的前进:这儿把上下文的切换次数从4次章鱼彩票电脑-还不明白零复制(Zero-Copy)?怎样称得上高档程序员削减到2次,一起也把数据copy的次数从4次下降到了3次。

            可是这是Zero-Copy么,答案是否定的。

            进阶

            Linux 2.1内核开端引入了sendfile函数(上一节有说到),用于将文件通过socket传送。

            sendfile(socket,章鱼彩票电脑-还不明白零复制(Zero-Copy)?怎样称得上高档程序员 file, len)章鱼彩票电脑-还不明白零复制(Zero-Copy)?怎样称得上高档程序员;

            该函数通过一次体系调用完成了文件的传送,削减了本来read/write方法的形式切换。此外更是削减了数据的copy, sendfile的具体进程如图:

            通过sendfile传送文件只需求一次体系调用,当调用sendfile时:

            1. 首要(通过DMA)将数据从磁盘读取到kernel buffer中;
            2. 然后将kernel buffer复制到socket buffer中;
            3. 最终将socket buffer中的数据copy到网卡设备(protocol engine)中发送;

            这个进程便是第二节(胪陈)中的那个进程。

            sendfiel与read/write形式比较,少了一次copy。可是从上述进程中也能够发现从kernel buffer中将数据copy到socket buffer是没有必要的。

            Linux2.4 内核对sendfile做了改善,如图:

            改善后的处理进程如下:

            1. 将文件复制到kernel buffer中;
            2. 向socket buffer中追加当时要发作的数据在kernel buffer中的方位和偏移量;
            3. 依据socket buffer中的方位和偏移量直接将kernel buffer的数据copy到网卡设备(protocol engine)中;

            通过上述进程,数据只通过了2次copy就从磁盘传送出去了。

            这个才是真实的Zero-Copy(这儿的零复制是针对kernel来讲的,数据在kernel形式下是Zero-Copy)。

            正是Linux2.4的内核做了改善,Java中的TransferTo()完成了Zero-Copy,如下图:

            Zero-Copy技能的运用场景有许多,比方Kafka, 又或许是Netty等,能够大大提高程序的功能。

            版权声明:本文为CSDN博主「朱小厮」的原创文章,遵从 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

            原文链接:https://blog.cs章鱼彩票电脑-还不明白零复制(Zero-Copy)?怎样称得上高档程序员dn.net/u013256816/article/details/52589524

            请关注微信公众号
            微信二维码
            不容错过
            Powered By Z-BlogPHP