在派生之前或之后在磁盘文件上调用mmap()有什么区别?

时间:2019-04-26 17:21:12

标签: linux memory-management fork mmap

我一直在努力了解mmap()如何与磁盘支持的文件一起使用,并且大多数情况下都可以使用它,但是我仍然有这个问题。

在主进程派生一堆辅助子进程以及文件支持的只读m​​mapped db的情况下,mmap是否发生在派生之前的主进程中或子进程中很重要?

我的理解是,如果它发生在派生之前在主进程中,那么在内存页表中,所有的映射 页面具有读取时设置为页面错误的设置,触发内核从磁盘(或页面高速缓存)加载页面,并且在派生一个孩子的页面后,将意味着该页面位于页面中。 mmap已准备好供其他孩子阅读而不会引起重大页面错误。

但是,如果在分叉之后的子进程中发生了mmap,其他工作人员子进程是否会受益于共享这些已加载的页面-它们是否都使用相同的基础mmap有效?还是每个工作人员的孩子都必须触发页面错误并自己加载每个页面?

1 个答案:

答案 0 :(得分:2)

它对页面错误活动没有影响。文件的页面映射对于OS是全局的,它表示特定页面是否在RAM中。映射了文件的每个进程的PTE都指向此公共数据结构。尝试访问不在RAM中的页面的第一个进程只会出现页面错误。这将触发它被读入,并且其他尝试访问同一页面的进程将能够使用该RAM。

两种情况之间的区别是分配给映射块的虚拟地址是否相同。如果在派生之前调用mmap,该地址将在所有子代中复制。如果在分叉后调用mmap,则它们可能会获得不同的地址。如果需要,在所有进程中使用相同的地址可使您将指针传递到进程之间的映射块中。您可以在块内的对象之间使用指针。如果它们并非都位于同一地址,则需要使用偏移量,并且所有进程都必须将偏移量添加到基址。