内存映射文件系统调用 - linux
当我们将文件映射到内存时,需要进行系统调用。后续对该文件的访问是否需要系统调用,或者进程的虚拟内存页面是否映射到内存中的实际页面缓存?
更新: 我还想知道的是,如果多个进程通过 mmap 访问同一个文件。他们将访问相同的物理内存部分写入。
When we map a file to memory, a system call is required. Do subsequent accesses to the file require system calls or is the virtual memory page of the process mapped to the actual page cache in memory?
update:
what i also want to know is that if multiple processes are accessing the same file through mmap. they will be accessing the same physical memory portion write.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不需要额外的系统调用(由您的进程),您只需像访问常规内存一样访问它即可。完成文件后,只需调用
munmap
。有关详细信息,请参阅此处的手册页。
编辑澄清:
我是说该函数将文件映射到调用进程的内存空间并返回指向内存块开头的指针。
例如,如果有两个不同的进程使用 MAP_SHARED 标志映射同一个文件,则每个进程将访问相同的物理内存,但该内存可能会映射到每个进程的虚拟内存中的不同位置空间,即每个进程的虚拟内存空间中mmap返回的指针可能不相等。
这就提出了这样一个观点:如果您需要在共享内存块内存储指针,那么这些指针只有在存储为相对于块/文件开头的偏移量时才有用,并且它们只能有效地指向块/文件内部的位置。
No need for additional system calls ( by your process ), you just access it like regular memory. When you're done with the file, just call
munmap
.See the man page here for details.
Edit For clarification:
I'm saying that the function maps the file into the calling process's memory space and returns a pointer to the beginning of the memory block.
For example, if you have two different processes map the same file with the
MAP_SHARED
flag then each process will be accessing the same physical memory, but that memory may be mapped at a different location in each process's virtual memory space, i.e. the pointers returned by mmap in each process's virtual memory space may not be equal.This brings up the point that if you for instance need to store pointers inside the shared memory block those pointers would only be useful if they were stored as offsets relative to the beginning of the block / file and they would only be able to usefully point to locations internal to the block / file.
当您映射文件时,Linux 在 MMU(内存管理单元)中创建条目。 MMU 监视 CPU 对真实 RAM 的所有读写操作。这样,它就知道您何时访问
mmap()
返回的内存部分。读取尚未在真实 RAM 中的部分将导致页面错误。 MMU 将捕获它们并调用内核例程将文件的正确部分加载到 RAM 中的某处,然后它将更新 MMU 表中的条目,以便数据现在位于mmap( )
给了你。事实上,它会在其他地方,但 MMU 会让它完全透明。当你写入内存时,MMU会将修改的页面标记为“脏”。当它们被刷新时(因为您访问了更多文件或因为您调用了 munmap()),更改将被写入磁盘。
因此,每次发生页面错误和脏页刷新时,都会发生系统调用。但由于页面大小为 4 或 8KB,因此这种情况很少发生。而且,内核一次会加载多个页面,因此系统调用的次数再次减少。最后,使用相同的代码来实现交换,因此非常优化。
所有这些效果使得 mmap 如此高效。
When you mmap a file, Linux creates entries in the MMU (memory management unit). The MMU watches over all reads and writes of the CPU to the real RAM. This way, it knows when you access parts of the memory which
mmap()
returned. Reading parts which are not yet in the real RAM will cause page faults. The MMU will catch them and call a kernel routine to load the right part of the file into RAM somewhere and then it will update the entry in the MMU table so it appears that the data is now located at the address whichmmap()
gave you. In fact, it will be somewhere else but the MMU will make this completely transparent.When you write to the memory, the MMU will mark the modified pages as "dirty". When they are flushed out (because you access more of the file or because you call
munmap()
), then the changes will be written out to disk.So every time a page fault and a dirty page flush happens, a system call happens. But since pages are 4 or 8KB, these happen rarely. Also, the kernel will load more than a single page at a time, so the number of system calls is reduced again. Lastly, the same code is used to implement swapping, so it is very optimized.
All these effects make mmap so efficient.