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

内存映射文件系统调用-linux,linux,file,mmap,memory-mapped-files,Linux,File,Mmap,Memory Mapped Files,当我们将文件映射到内存时,需要进行系统调用。对文件的后续访问是否需要系统调用,或者进程的虚拟内存页是否映射到内存中的实际页面缓存 更新: 我还想知道的是,如果多个进程通过mmap访问同一个文件。它们将访问相同的物理内存部分写入。无需额外的系统调用(通过您的进程),您只需像常规内存一样访问它。处理完文件后,只需调用munmap 返回值 成功后,mmap() 返回指向映射区域的指针。 出现错误时,值MAP\u失败 返回的是,(void*)-1),并且 errno设置正确。在…上 成功,munmap(

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

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

无需额外的系统调用(通过您的进程),您只需像常规内存一样访问它。处理完文件后,只需调用
munmap

返回值

成功后,
mmap()
返回指向映射区域的指针。 出现错误时,值
MAP\u失败
返回的是,(void*)-1),并且
errno设置正确。在…上
成功,
munmap()
在 故障-1,并且设置了
errno
(可能 到
EINVAL

编辑澄清:

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

例如,如果有两个不同的进程使用
map\u SHARED
标志映射同一文件,则每个进程将访问相同的物理内存,但该内存可能映射到每个进程虚拟内存空间中的不同位置,也就是说,mmap在每个进程的虚拟内存空间中返回的指针可能不相等


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

无需额外的系统设置调用(通过您的进程),您只需像常规内存一样访问它。处理完文件后,只需调用
munmap

返回值

成功后,
mmap()
返回指向映射区域的指针。 出现错误时,值
MAP\u失败
返回的是,(void*)-1),并且
errno设置正确。在…上
成功,
munmap()
在 故障-1,并且设置了
errno
(可能 到
EINVAL

编辑澄清:

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

例如,如果有两个不同的进程使用
map\u SHARED
标志映射同一文件,则每个进程将访问相同的物理内存,但该内存可能映射到每个进程虚拟内存空间中的不同位置,也就是说,mmap在每个进程的虚拟内存空间中返回的指针可能不相等


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

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

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

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


所有这些效果都使mmap非常有效。

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

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

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


所有这些效果使mmap非常有效。

指针位于映射到实际文件的虚拟地址空间中。现在,对该指针指向的内存执行读写操作不需要系统ca