7

我已经开始阅读有关内存映射 IO 的内容,但在理解这些概念时遇到了一些困难

这是我到目前为止所理解的:

每个进程都有一个虚拟地址空间。内存映射文件在虚拟地址空间中分配了一个特定的地址范围,该地址映射到物理内存上的相同地址。这样,磁盘控制器在
内存上完成的所有写入(通过 DMA)都将反映到进程中,而无需任何额外的复制。(在非内存映射文件的情况下,CPU 必须将内容复制到进程的缓冲区)。

我的疑惑:

  • 我的理解正确吗?

  • 如果有多个进程试图对一个文件进行 mmap 并且没有可用于直接映射的连续内存块会发生什么?

4

1 回答 1

7

内存子系统本身对“文件”这个操作系统概念没有任何理解,并且已经出现了一些操作系统根本不使用文件。您对工作原理的理解很接近,但有点偏离mmap

每个进程都有自己的虚拟地址空间,这可能与物理内存几乎没有关系(很多虚拟地址空间根本没有任何关联的内存,永远,换出的虚拟内存没有任何物理内存)。系统使用某种查找表(在 x86 上称为描述符表)来指定哪些虚拟地址范围映射到哪些物理地址范围。非“驻留”的虚拟内存(已换出、mmapped 但未加载)有一个“不存在”条目。

每当程序尝试访问此内存时,CPU 都会导致页面错误,这会告诉操作系统在某处找到适当的内容并将它们加载到物理内存中。在交换的情况下,内容是从交换文件或分区中加载出来的;在 的情况下mmap,它们是从文件系统的某个地方加载出来的。

将它们放入物理内存和更新描述符表的机制可能会有所不同。您所描述的是 DMA,它允许驱动控制器将内容直接复制到一块物理内存中,以及零复制 I/O,这是一种技术,操作系统只是创建一个新的描述符映射,告诉处理器“传送" 物理内存区域进入程序的地址空间。技术上都不需要mmap(操作系统可以“手动”加载文件并将其复制到程序的新缓冲区中,这可能发生在读取-复制-更新情况下),但现代系统会像您描述的那样做。

物理内存不一定是连续的。当mmap调用 POSIX 版本时,操作系统会length为映射分配字节,但由于有了虚拟内存,这些字节可以分成多个块并由处理器映射在一起。

如果多个进程试图访问mmap同一个文件,操作系统的行为取决于访问是只读的还是读/写的;只读副本可以在许多进程之间共享(例如实际的可执行代码;这就是为什么即使 Chrome 可能有几十个进程在运行,Chrome 二进制文件只在内存中一次)。

于 2013-09-11T21:03:09.307 回答