mmap学习总结

buffer & cache

Cache 和 Buffer 都是缓存,主要区别是什么?

  • buffer(缓冲区)

主要目的是进行流量整形,把突发的大数量较小规模的 I/O 整理成平稳的小数量较大规模的 I/O,以减少响应次数(比如从网上下电影,你不能下一点点数据就写一下硬盘,而是积攒一定量的数据以后一整块一起写,不然硬盘都要被你玩坏了)。

  • cache(缓存)

是为了弥补高速设备和低速设备的鸿沟而引入的中间层,最终起到加快访问速度的作用。

page cache

内核会为每个文件单独维护一个page cache,用户进程对于文件的大多数读写操作会直接作用到page cache上,内核会选择在适当的时候将page cache中的内容写到磁盘上(当然我们可以手工fsync控制回写),这样可以大大减少磁盘的访问次数,从而提高性能。

page cache是linux内核文件访问过程中很重要的数据结构,page cache中会保存用户进程访问过得该文件的内容,这些内容以页为单位保存在内存中,当用户需要访问文件中的某个偏移量上的数据时,内核会以偏移量为索引,找到相应的内存页,如果该页没有读入内存,则需要访问磁盘读取数据。为了提高页得查询速度同时节省page cache数据结构占用的内存,linux内核使用树来保存page cache中的页。

page cache刷盘

脏页有两种刷盘的方式:

  1. 异步刷盘,脏页太多或者存在太久都会导致page cache回写磁盘,Linux中可以通过 sysctl -a | grep dirty 查看相关的控制参数;
  2. 调用fsync、msync等。

mmap & read/write

mmap为什么比read/write快

Page Cache

在了解了以上的基础之后,我们就来比较一下mmap和read/write的区别,先说一下read/write系统调用,read/write系统调用会有以下的操作:

  1. 访问文件,这涉及到用户态到内核态的转换;
  2. 读取硬盘文件中的对应数据,内核会采用预读的方式,比如我们需要访问100字节,内核实际会将按照4KB(内存页的大小)存储在page cache中;
  3. 将read中需要的数据,从page cache中拷贝到用户缓冲区中。

在这里插入图片描述

整个过程还是比较艰辛的,基本上涉及到用户内核态的切换,还有就是数据拷贝。

接下来继续说mmap吧,mmap系统调用是将硬盘文件映射到用内存中,说的底层一些是将page cache中的页直接映射到用户进程地址空间中,从而进程可以直接访问自身地址空间的虚拟地址来访问page cache中的页,这样会并涉及page cache到用户缓冲区之间的拷贝,mmap系统调用与read/write调用的区别在于:

  1. mmap只需要一次系统调用,后续操作不需要系统调用
  2. 访问的数据不需要在page cache和用户缓冲区之间拷贝

在这里插入图片描述

从上所述,当频繁对一个文件进行读取操作时,mmap会比read高效一些。

文件描述符

Linux的打开文件表:打开文件表、文件描述符、打开的文件句柄以及i-node之间的关系

img

原文地址:https://www.cnblogs.com/jmliao/p/12985730.html