Page cache
Linux系统中I/O操作的数据读写流程介绍 - 知乎 (zhihu.com)
深入理解Linux 的Page Cache - 知乎 (zhihu.com)
Linux中存在缓存IO(buffer IO)以及直接IO(direct IO),通常OS采用的是缓存IO,缓存的就是页缓存。
**页缓存(PageCache)**是操作系统对文件的缓存,用来减少对磁盘的 I/O 操作,以页为单位的,内容就是磁盘上的物理块,页缓存能帮助程序对文件进行顺序读写的速度几乎接近于内存的读写速度。一定要注意,页缓存并没有在计算机的高速缓存中,而是位于内核代码的内存中。
页缓存读取策略
当进程发起一个读操作 (比如,进程发起一个 read() 系统调用),它首先会检查需要的数据是否在页缓存中:
- 如果在,则放弃访问磁盘,而直接从页缓存中读取。
- 如果不在,则内核调度块 I/O 操作从磁盘去读取数据,并读入紧随其后的少数几个页面(不少于一个页面,通常是三个页面),然后将数据放入页缓存中。
假设要去读一个文件,如果是第一次读取,计算机的Cache中肯定不存在,那么open打开文件内核后建立了一系列的数据结构。
接下来调用 read,到达文件系统(内核)这一层,发现 Page Cache 中不存在该位置的磁盘映射,然后创建相应的 Page Cache 并和相关的扇区关联。
然后请求继续到达块设备层,在 IO 队列里排队,接受一系列的调度后到达设备驱动层,此时一般使用 DMA 方式读取相应的磁盘扇区到 Page Cache 中,然后 read 拷贝数据到用户提供的用户态 buffer 中去(read 的参数指出的,一般是字节数组),可见 Page Cache 的本质是由 Linux 内核管理的内存区域(内核空间缓冲区)。
页缓存写策略
当进程发起 write 系统调用写数据到文件中,先写到页缓存,然后方法返回。此时数据还没有真正的保存到文件中去,Linux 仅仅将页缓存中的这一页数据标记为 “脏”,并且被加入到脏页链表中。