关于MAP_PRIVATE与MAP_SHARED的mmap内存映射特性咨询
这问题问到点子上了,刚好是mmap两种常用标志的核心差异点,我分两部分给你解释清楚:
一、关于修改同步的问题
结论:PS/PH的修改不一定会被PV看到,PV也不是完全不受SHARED进程修改的影响,关键看PV有没有对对应内存页执行过写入操作。
咱们先搞懂MAP_PRIVATE的核心机制——写时复制(Copy-On-Write,简称COW):
- 当PV刚用
MAP_PRIVATE映射文件时,它的虚拟内存页和PS、PH(还有内核的文件页缓存)是共享同一块物理内存的。 - 如果PV还没对某块内存写过,那PS或PH通过
MAP_SHARED修改的内容会直接同步到共享的物理页(也就是页缓存),这时候PV去读这块内存,看到的就是修改后的内容。 - 但一旦PV对某块内存执行了写入操作,内核会立刻为PV复制出一块专属的物理页,把原来的内容拷贝过来,之后PV的读写都在这块私有页上进行。这时候不管PS/PH怎么改,都碰不到PV的私有页,PV也完全看不到他们的修改;反过来PV的修改也不会同步给别人——这就是你提到的“PV对内存块的修改不会同步到PS和PH”的底层原因。
二、关于物理内存分配的问题
结论:在三者都没执行写入操作的情况下,它们会共享同一块物理内存;MAP_SHARED和MAP_PRIVATE本身不会直接触发独立的物理内存分配,只有MAP_PRIVATE进程执行写入时才会触发COW分配私有页。
具体细节:
- mmap映射文件时,内核会先把文件内容加载到页缓存(这是物理内存的一部分),然后给进程的虚拟地址空间建立映射指向这些页缓存。
- 不管是
MAP_SHARED还是MAP_PRIVATE,只要进程没对映射内存执行写入,虚拟页都会直接指向页缓存的物理页——所以三个进程此时共享同一块物理内存,没有额外的物理内存分配。 - 只有当
MAP_PRIVATE的进程(也就是PV)写内存时,内核才会分配新的物理页,拷贝原页缓存的内容,然后把PV的虚拟页映射到这块新页上,实现“私有”。而MAP_SHARED的进程不管怎么写,都是直接修改共享的页缓存,不会分配新物理页(前提是文件本身可写,映射时没加PROT_READ限制)。
内容的提问来源于stack exchange,提问作者Viper Bailey
相关产品推荐
相关产品推荐

