当2个程序映射同一个文件时mmap如何工作

Lee*_*Lee 4 c linux mmap virtual-memory page-tables

我试图mmap在查看man mmap时了解其工作原理。

据我了解,它向页表添加了一个映射,该映射在文件和虚拟地址(这是给定的地址void *addr)之间进行映射

那么,当两个程序映射同一个文件时会发生什么?页表中是否有 2 个条目,每个程序一个?

chq*_*lie 6

那么,当两个程序映射同一个文件时会发生什么?页表中是否有 2 个条目,每个程序一个?

在现代操作系统中,每个进程都有自己的内存页表,该页表可能指向与其他用户和内核进程共享的物理内存页。

使用MAP_SHARED,此映射是共享的:映射此文件的其他进程可以看到映射的更新,并传递到底层文件。在调用 msync(2) 或 munmap() 之前,该文件可能不会真正更新。

这看起来很有趣,但有很多警告:

  • 两个进程为同一文件映射的实际页面可能驻留在每个进程中的相同地址或不同地址,将指针存储到此共享内存中可能不允许其他进程使用它们,因为它们可能指向不一致的地址。

  • 该实现可以对两种映射使用相同的物理内存页,也可以不使用:由于微妙的原因(缓存策略、不同步读取......),即使它是相同的物理内存,一个进程对其内存所做的修改也可能不会立即反映在其他进程的内存中。

read因此,映射文件或通过流 API 读取文件的其他进程可能会或可能不会看到修改FILE*

如果其中一个进程调用msync(),则修改应该在所有映射中以及文件的所有尚未读取的部分中可见,请记住FILE*流 API 可能已在内部非共享缓冲区中缓冲了一些数据:该区域中的修改将不会反映出来。

结论:使用这些机制实现进程间通信是有风险且不可靠的。该行为可能取决于系统特定特征,例如操作系统策略、CPU 和缓存架构、使用的 RAM 类型、时钟速度以及谁知道还有什么。依赖经过验证的 API 更安全,这些 API 确实可以使用映射内存实现,但前提是知道它提供正确的语义。