内存映射文件系统调用--linux

时间:2009-11-18 08:28:49

标签: linux file mmap memory-mapped-files

当我们将文件映射到内存时,需要进行系统调用。对文件的后续访问是否需要系统调用,还是映射到内存中实际页面缓存的进程的虚拟内存页?

更新: 我还想知道的是,如果多个进程通过mmap访问同一个文件。他们将访问相同的物理内存部分写。

2 个答案:

答案 0 :(得分:4)

当您映射文件时,Linux会在MMU(内存管理单元)中创建条目。 MMU监视CPU对真实RAM的所有读写操作。这样,它就知道您何时访问mmap()返回的内存部分。读取尚未存在于实际RAM中的部分将导致页面错误。 MMU将捕获它们并调用内核例程将文件的正确部分加载到某个RAM的RAM中,然后它将更新MMU表中的条目,这样看起来数据现在位于mmap()的地址给你。事实上,它将在其他地方,但MMU将使这完全透明。

当您写入内存时,MMU会将修改后的页面标记为“脏”。当它们被刷新时(因为您访问了更多文件或因为您调用了munmap()),所以更改将被写入磁盘。

因此,每次发生页面错误和脏页面刷新时,都会发生系统调用。但由于页面为4或8KB,因此很少发生。此外,内核将一次加载多个页面,因此系统调用次数再次减少。最后,相同的代码用于实现交换,因此它非常优化。

所有这些效果使mmap如此高效。

答案 1 :(得分:3)

无需额外的系统调用 (按您的流程) ,您只需像常规内存一样访问它。完成该文件后,只需致电munmap

  

返回值

     

成功时,mmap()   返回指向映射区域的指针。   出错时,值为MAP_FAILED(即   是,(void *) - 1)返回,和   errno设置得恰当。上   成功,munmap()返回0,开启   失败-1,并设置errno(可能   到EINVAL)。

See the man page here for details

编辑澄清:

我说该函数将文件映射到调用进程的内存空间,并返回指向内存块开头的指针。

例如,如果您有两个不同的进程使用MAP_SHARED标志映射相同的文件,则每个进程将访问相同的物理内存,但该内存可能映射到每个进程的虚拟内存中的不同位置空间,即mmap在每个进程的虚拟内存空间中返回的指针可能不相等。

这提出了这样的观点:如果你需要在共享内存块中存储指针,那么这些指针只有在相对于块/文件的开头存储为偏移量时才有用,并且它们只能够有用地指向块/文件内部的位置。