拷贝

零拷贝 zero-copy 原理

点点圈 提交于 2019-12-10 13:11:18
引言 传统的 Linux 操作系统的标准 I/O 接口是基于数据拷贝操作的,即 I/O 操作会导致数据在操作系统内核地址空间的缓冲区和应用程序地址空间定义的缓冲区之间进行传输。这样做最大的好处是可以减少磁盘 I/O 的操作,因为如果所请求的数据已经存放在操作系统的高速缓冲存储器中,那么就不需要再进行实际的物理磁盘 I/O 操作。但是数据传输过程中的数据拷贝操作却导致了极大的 CPU 开销,限制了操作系统有效进行数据传输操作的能力。 零拷贝( zero-copy )技术可以有效地改善数据传输的性能,在内核驱动程序(比如网络堆栈或者磁盘存储驱动程序)处理 I/O 数据的时候,零拷贝技术可以在某种程度上减少甚至完全避免不必要 CPU 数据拷贝操作。 什么是零拷贝? 零拷贝就是一种避免 CPU 将数据从一块存储拷贝到另外一块存储的技术。针对操作系统中的设备驱动程序、文件系统以及网络协议堆栈而出现的各种零拷贝技术极大地提升了特定应用程序的性能,并且使得这些应用程序可以更加有效地利用系统资源。这种性能的提升就是通过在数据拷贝进行的同时,允许 CPU 执行其他的任务来实现的。 零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除传输数据在存储器之间不必要的中间拷贝次数,从而有效地提高数据传输效率。而且,零拷贝技术减少了用户应用程序地址空间和操作系统内核地址空间之间因为上下文切换而带来的开销

[Python]什么是浅拷贝,深拷贝

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-10 05:37:16
浅拷贝是指拷贝的只是原对象元素的引用,换句话说,浅拷贝产生的对象本身是新的,但是它的内容不是新的,只是对原对象的一个引用。这里有个例子 >>> aList=[[1, 2], 3, 4] >>> bList = aList[:] #利用切片完成一次浅拷贝 >>> id(aList) 3084416588L >>> id(bList) 3084418156L >>> aList[0][0] = 5 >>> aList [[5, 2], 3, 4] >>> bList [[5, 2], 3, 4] 可以看到,浅拷贝生产了一个新的对象bList,但是aList的内容确实对aList的引用,所以但改变aList中值的时候,bList的值也跟着变化了。 但是有点需要特别提醒的,如果对象本身是不可变的,那么浅拷贝时也会产生两个值,见这个例子: >>> aList = [1, 2] >>> bList = aList[:] >>> bList [1, 2] >>> aList [1, 2] >>> aList[1]=111 >>> aList [1, 111] >>> bList [1, 2] 为什么bList的第二个元素没有变成111呢?因为数字在python中是不可变类型!! 这个顺便回顾下Python标准类型的分类: 可变类型: 列表,字典 不可变类型:数字,字符串,元组 理解了浅拷贝

js实现浅拷贝和深拷贝

独自空忆成欢 提交于 2019-12-10 03:52:13
浅拷贝和深拷贝都只针对于像Object, Array这样的复杂对象, 区别:浅拷贝只复制对象的第一层属性、深拷贝可以对对象的属性进行递归复制 如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化,这种叫浅拷贝。 深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。 一、浅拷贝 1、数组的浅拷贝 (1)、可用concat、slice返回一个新数组的特性来实现拷贝 var arr = ['old', 1, true, null, undefined]; var new_arr = arr.concat(); // 或者var new_arr = arr.slice()也是一样的效果; new_arr[0] = 'new'; console.log(arr); // ["old", 1, true, null, undefined] console.log(new_arr); // ["new", 1, true, null, undefined]/2、 (2)、还有for循环也能实现数组的浅拷贝 var arr = [1,2,3,4,5] var arr2 = copyArr(arr) function copyArr(arr) { let

js深浅拷贝

倖福魔咒の 提交于 2019-12-10 00:02:16
在js中,经常要对数组进行拷贝操作,但如果只是简单的将它赋予其他变量,那么之后只需要修改一个变量,其他的就都会受到影响一起改变。这便是数组的深浅拷贝问题,像这种直接赋值的方式就是浅拷贝,但很多时候,这样并不是我们想要得到的结果。 举个例子: var arr1 = [0,1,2,3]; var arr2 = arr1; arr2[1] = "hello"; console.log(arr1); // [0,'hello',2,3] 由上可知,修改了 arr2 之后,arr1 也随之改变了。同样,在js中对象的拷贝操作也是如此。 var obj1 = { name: 'test', color: 'blue' } var obj2 = obj1; obj2.color = 'red'; console.log(obj1.color); // 'red' 1. 深浅拷贝 js大致分成两种数据类型:基本数据类型和引用数据类型。 基本数据类型保存在栈内存,而引用类型则保存在堆内存中。对于基本数据类型的拷贝,并没有深浅拷贝的区别,我们所说的深浅拷贝都是对于引用数据类型而言的。 浅拷贝: 浅拷贝是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响。 深拷贝: 深拷贝不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制

常用拷贝和替换算法

痴心易碎 提交于 2019-12-09 22:49:17
1.copy:容器中指定范围内元素拷贝到另一个容器中 # include "pch.h" # include <iostream> # include <vector> # include <algorithm> # include <string> using namespace std ; //copy void test01 ( ) { vector < int > v ; for ( int i = 0 ; i < 10 ; i ++ ) { v . push_back ( i ) ; } vector < int > v2 ; v2 . resize ( v . size ( ) ) ; copy ( v . begin ( ) , v . end ( ) , v2 . begin ( ) ) ; } 2.replace://将容器内指定范围的旧元素修改为新元素 //replace void test01 ( ) { vector < int > v ; for ( int i = 0 ; i < 10 ; i ++ ) { v . push_back ( i ) ; } replace ( v . begin ( ) , v . end ( ) , 8 , 1 ) ; } 3.replace_if://将容器内指定范围的满足条件的旧元素修改为新元素 //replace

列表的深浅拷贝

╄→гoц情女王★ 提交于 2019-12-09 21:40:27
在python中的数据类型包括:bool、int、float、str、set、list、tuple、dict等 等。 我们可以大致将这些数据类型归类为简单数据类型和复杂的数据类型 简单数据类型: bool、int、float、str。 复杂数据类型:list、tuple、set、dict 对于简单数据类型变量在内存中保存的形式如下: str1 = "hello world" print ( id ( str1 ) ) str1 = "hello world" print ( id ( str1 ) ) str1 = "new hello world" print ( id ( str1 ) ) 结果: 2537704755568 2537704755568 2537704755888 对于复杂数据类型变量在内存中保存的形式如下: 列表中保存的是数据的内存地址而不是数据本身。 lst = [ 1 , 2 , 3 ] lst . append ( 4 ) print ( id ( lst ) ) lst = [ 1 , 2 , 3 ] print ( id ( lst ) ) lst = [ 4 , 5 , 6 ] print ( id ( lst ) ) 结果: 2390675657096 2390675657416 2390675657096 浅拷贝 对于浅copy来说

IO并发原理

我们两清 提交于 2019-12-09 20:12:45
并发原理: 几乎所有的 IO 接口都是阻塞型的,处理过程中线程将被阻塞,无法进行任何操作直到返回调用结果,或超时。 IO 模型:系统内核 和 一个调用这个 IO 的线程 第一步 等待数据准备 第二部 将数据从内核拷贝到进程中 传统阻塞 IO 用户线程发送 IO 请求( read 操作)到系统内核,系统内核首先进行数据准备,然后进行数据拷贝。这两个过程中用户线程是完全阻塞的状态,啥也干不了。 非阻塞 IO 用户线程发出 IO 请求,系统内核会开始准备数据并且直接返回一个 error ,然后用户线程接收到返回值可以非阻塞(干别的了)。然后用户线程不断地发送请求,时刻询问,如果系统内核没准备好就还是返回 error ,如果准备好就直接拷贝数据,拷贝过程中是阻塞的。 多路复用 IO 多了一个 select ,用来实时监听多个 socket 是否准备好。当任意 socket 准备好了 select 就会返回,用户就会调用 read ,系统进行拷贝工作。 优点: select 只占用单线程,不消耗太多资源,可以同时处理多个连接 异步 IO 用户线程发出 IO 请求后,系统内核接收到请求会立刻给个返回,使用户线程不会阻塞。 然后系统内核自己等待数据准备,然后拷贝到用户内存,完成后通知一下用户线程。 来源: https://www.cnblogs.com/ttaall/p/12013136

postgresql----COPY之表与文件之间的拷贝

一曲冷凌霜 提交于 2019-12-09 15:33:42
postgresql提供了COPY命令用于表与文件(和标准输出,标准输入)之间的相互拷贝,copy to由表至文件,copy from由文件至表。 示例1.将整张表拷贝至标准输出 test=# copy tbl_test1 to stdout; 1 HA 12 2 ha 543 示例2.将表的部分字段拷贝至标准输出,并输出字段名称,字段间使用','分隔 test=# copy tbl_test1(a,b) to stdout delimiter ',' csv header; a,b 1,HA 2,ha 示例3.将查询结果拷贝至标准输出 test=# copy (select a,b from tbl_test1 except select e,f from tbl_test2 ) to stdout delimiter ',' quote '"' csv header; a,b 2,ha 将标准输入拷贝至表中需要注意几点 1.字段间分隔符默认使用【Tab】键 2.换行使用回车键 3.结束使用反斜线+英文据点(\.) 4.最好指定字段顺序,要不然可能会错位赋值 示例4.将标准输入拷贝至表中 test=# copy tbl_test1(a,b,c) from stdin; Enter data to be copied followed by a newline. End with

Linux: cp 复制文件(文件夹)

女生的网名这么多〃 提交于 2019-12-09 14:22:38
参数 a 该选项通常在拷贝目录时使用。它保留链接、文件属性,并递归地拷贝目录,其作用等于dpR选项的组合。 d 拷贝时保留链接。 f 删除已经存在的目标文件而不提示。 i 和f选项相反,在覆盖目标文件之前将给出提示要求用户确认。回答y时目标文件将被覆盖,是交互式拷贝。 p 此时cp除复制源文件的内容外,还将把其修改时间和访问权限也复制到新文件中。 r 若给出的源文件是一目录文件,此时cp将递归复制该目录下所有的子目录和文件。此时目标文件必须为一个目录名。 l 不作拷贝,只是链接文件。 1、复制文件到文件夹 cp /home/downloads/xampp-linux-x64-7.3.6-0-installer.run /opt/ 2、复制文件夹到文件夹 cp -r /home/downloads/phpcms_v9_UTF8/install_package/ /opt/lampp/htdocs/ 来源: https://www.cnblogs.com/T8888/p/12010566.html

TCP之深入浅出send和recv

坚强是说给别人听的谎言 提交于 2019-12-09 12:26:55
在这篇文章中,我用深入浅出socket选项行为中的4个选项来介绍send和recv的行为 SO_RCVBUF SO_SNDBUF 先明确一个概念:每个TCP socket在内核中都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式以及TCP的滑动窗口便是依赖于这两个独立的buffer以及此buffer的填充状态。接收缓冲区把数据缓存入内核,应用进程一直没有调用read进行读取的话,此数据会一直缓存在相应socket的接收缓冲区内。再啰嗦一点,不管进程是否读取socket,对端发来的数据都会经由内核接收并且缓存到socket的内核接收缓冲区之中。read所做的工作,就是把内核缓冲区中的数据拷贝到应用层用户的buffer里面,仅此而已。进程调用send发送的数据的时候,最简单情况(也是一般情况),将数据拷贝进入socket的内核发送缓冲区之中,然后send便会在上层返回。换句话说,send返回之时,数据不一定会发送到对端去(和write写文件有点类似),send仅仅是把应用层buffer的数据拷贝进socket的内核发送buffer中。后续我会专门用一篇文章介绍read和send所关联的内核动作。每个UDP socket都有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发,不管对方是否可以正确接收,所以不缓冲,不需要发送缓冲区。