目录
-
传统的 System Call I/O
-
读操作
-
写操作
-
网络 I/O
-
磁盘 I/O
-
高性能优化的 I/O
-
存储设备的 I/O 栈
-
I/O Buffering
传统的 System Call I/O
在 Linux 系统中,传统的访问方式是通过 write() 和 read() 两个系统调用实现的,通过 read() 函数读取文件到到缓存区中,然后通过 write() 方法把缓存中的数据输出到网络端口。
下图分别对应传统 I/O 操作的数据读写流程,整个过程涉及 2 次 CPU 拷贝、2 次 DMA 拷贝,总共 4 次拷贝,以及 4 次上下文切换。
-
CPU 拷贝: 由 CPU 直接处理数据的传送,数据拷贝时会一直占用 CPU 的资源。
-
DMA 拷贝: 由 CPU 向DMA磁盘控制器下达指令,让 DMA 控制器来处理数据的传送,数据传送完毕再把信息反馈给 CPU,从而减轻了 CPU 资源的占有率。
-
上下文切换: 当用户程序向内核发起系统调用时,CPU 将用户进程从用户态切换到内核态; 当系统调用返回时,CPU 将用户进程从内核态切换回用户态。
读操作
当应用程序执行 read 系统调用读取一块数据的时候,如果这块数据已经存在于用户进程的页内存中,就直接从内存中读取数据。
如果数据不存在,则先将数据从磁盘加载数据到内核空间的读缓存(Read Buffer)中,再从读缓存拷贝到用户进程的页内存中。
read(file_fd, tmp_buf, len);
基于传统的 I/O 读取方式,read 系统调用会触发 2 次上下文切换,1 次 DMA 拷贝和 1 次 CPU 拷贝。
发起数据读取的流程如下:
-
用户进程通过 read() 函数向 Kernel 发起 System Call,上下文从 user space 切换为 kernel space。
-
CPU 利用 DMA 控制器将数据从主存或硬盘拷贝到 kernel space 的读缓冲区(Read Buffer)。
-
CPU 将读缓冲区(Read Buffer)中的数据拷贝到 user space 的用户缓冲区(User Buffer)。
-
上下文从 kernel space 切换回用户态(User Space&#