常见I/O类型:缓冲I/O和直接I/O
缓冲I/O是C语言提供的库函数
直接I/O是Linux系统API
应用程序内存:代码中用malloc/free,new/delete 等分配出来的内存
用户缓冲区:C语言的FILE结构体里面的bufer.
内核缓冲区:Linux操作系统的Page Cache. 1Page 一般为4K
缓冲I/O的读操作有3次数据拷贝,写操作有3次数据拷贝
读:磁盘–>内核缓冲区–>用户缓冲区–>应用程序内存
写:应用程序内存–>用户缓冲区–>内核缓冲区–>磁盘
直接I/O的读操作有2次数据拷贝,写操作有2次数据拷贝
读:磁盘–>内核缓冲区–>应用程序内存
写:应用程序内存–>内核缓冲区–>磁盘
内存映射:当用户空间没有物理内存,直接拿应用程序的逻辑内存地址映射到Linux操作系统的内核缓冲区,所谓的应用程序逻辑内存其实就是内核缓冲区
读:磁盘–>内核缓冲区
写:内核缓冲区–>磁盘
零拷贝
普通的数据发送会涉及到用户空间和内核空间的映射,
零拷贝技术
零拷贝技术使内核缓冲区和Socket缓冲区之间并没有做数据拷贝,只是一个
地址的映射,底层的网卡驱动程序读取数据并发送到网络时,看似读的是Socket
缓冲区的数据,但实际读的是内核缓冲区的数据.
映射和拷贝的区别:拷贝是把数据从一块内存中复制到另外一块内存中.映射相当于只是持有了数据的一个引用(或地址),数据本身只有一份.
这里所谓的零拷贝,是从内存角度来看,数据在内存中没有发生过数据拷贝,只在内存和I/O之间传输