相信熟悉进程间通信的人们都清楚,最快的ICP方式目前是MMAP。至于为什么MMAP是最快的ICP方式呢,我查阅了很多资料,主要原因是MMAP的通信方式不需要系统调用,自然也不涉及数据在内核空间和用户空间之间的拷贝了。但是对于MMAP的详细流程,以及为什么不需要系统调用,很多文章讲的却不是很清楚。在综合了多处资料之后,我尝试对MMAP的原理进行解释:


如图所示,左侧为进程的地址空间布局,其中有一部分就是MMAP区域。

接下来我们从函数调用开始梳理一下操作系统中发生的流程:

1、进程调用了【用户空间的MMAP函数】,该函数封装了MMAP的系统调用

2、进程申请相关内存区域

3、进程找到入参中的文件对应的物理地址:

- 通过fd查询进程打开文件表,得到系统打开文件表中对应fd的指针

- 查询系统打开文件表,找到inode指针

4、函数调用【MMAP的系统调用】:int mmap(struct file *filp, struct vm_area_struct *vma),传入刚才申请的内存区域和找到的fcb信息,将二者的关系写入进程的页表之中

那么在实际使用的过程中,对于MMAP内存区域的读写操作,其实是复用了部分虚拟内存的逻辑:

1、 进程在MMAP区域进行读写都是纯内存操作,所以无须进行系统调用(不需要进内核态);

2、当进程未载入MMAP相应的内存页时,则会引发缺页异常,从而将对应内存页面载入当前进程的页表中;

3、当该部分区域的内存页存在于物理内存时,两个进程的写操作都会直接体现在物理内存

那么MMAP与虚拟内存的区别是:

1、多进程可以复用同一块页框:当A进程引发缺页异常将数据从硬盘调入页框后,B进程因为页表中状态为未载入,仍会引发缺页异常,但是不用再次从硬盘调入,直接复用即可

2、需要定期将“脏页”回写到硬盘中:虚拟内存中的页如果不被调出,不需要写入磁盘;