mmap 通过地址映射读写文件

预备知识

理解mmap,首先要理解什么是用户态和内核态,其次要了解虚拟内存。

简单的说,用户态内核态指的就是cpu指令集的权限程度,我们用户程序并没有操作硬件的权限,于是很多操作都需要转为内核态才能被执行。我们的物理内存也是分为用户空间和内核空间的,比如32位处理器的寻址范围为4G,那么低地址的3G就是用户空间,高地址的1G是内核空间。

其次是虚拟内存,虚拟内存是一种感受,我们作为os的使用者,能加载的程序大小其实可以超过物理内存,这是因为内存空间不足时,访问一个不存在于内存的数据,会触发缺页中断,进而会将内存中不常用的页置换到磁盘,将磁盘中要访问的数据置换到内存,如此我们作为使用者感觉内存似乎非常大。

除此之外,我们运行的程序都有属于自己的内存空间,这些程序也是被os欺骗了的,这些地址空间在程序看来是连续的,但实际存储在物理内存上是不连续的,cpu可以通过mmu将虚拟地址转为实际物理地址。(我们用户态太卑微了hhh~)

mmap和标准IO

一般我们读写文件调用的都是系统标准IO,比如系统调用函数read,write等等。标准IO在读写数据时都涉及到用户态和内核态的转换,比如read文件,就需要到内核空间的页缓存(page cache)中查找是否有该页,如果没有,那么就需要从磁盘中调取该页进入内核页缓存中,然后再将该页中的数据传输到用户空间(read函数的buf数组)。当write文件时,也是查找内核空间,将数据传入内核空间的页缓存,内核再将数据延迟刷入磁盘。

而mmap使得进程中的某一段地址和磁盘上文件的某一段地址形成映射,准确的说,应该是和页缓存中的页地址形成了映射,这样直接对进程中的那段地址做操作,虚拟内存会直接将该地址映射到页缓存上,进而直接操作了页缓存(page cache是被用户态和内核态共享的区域)。那么就无需页缓存再拷贝数据到用户空间了~

减少了一次页缓存到用户空间的数据拷贝,mmap自然比标准IO快了。

关于mmap的具体使用和参数含义,可以查看参考链接中的介绍。

参考:
https://segmentfault.com/a/1190000039774784
https://juejin.cn/post/6956031662916534279
https://www.cnblogs.com/longchang/p/11162813.html
https://www.cnblogs.com/huxiao-tee/p/4660352.html

posted @ 2021-12-05 02:46  moon_orange  阅读(65)  评论(0编辑  收藏  举报