1
char *p = (char*) mmap(...);
....; /* check if p is not -1 */
a = *p;

在运行最后一条语句时,发生页面错误。内核中的故障处理程序将在物理内存中分配一个页面并将文件中的 4K 字节复制到该页面中,然后修改页面条目。读取的指令*p将再次执行,这次成功。

但是故障处理程序如何知道与页面关联的文件名和路径。文件名(或fd)存储在哪里?以及文件中的偏移量。

如果进程的数据段中的页面被换出(我猜是交换文件)怎么办?当稍后需要换入页面时,内核如何知道从哪里复制?

4

1 回答 1

0

处理程序不知道文件名或路径,因为它不使用它们(您可以知道,因为即使在创建映射后从文件系统中删除了文件,映射仍然可以正常工作;文件内容保持有效,直到所有打开的文件描述符和内存映射都关闭)。

它不使用fd任何一个;您可以close在调用后立即fd传递到,并且映射仍然有效(这实际上在某些具有低s 的打开文件句柄的系统上是必需的;您可以一次映射 10,000 个文件,但您无法保持打开如果fds 为 1000,则为所有这些)。mmapmmapulimitfdulimit

发生的情况是,mmap操作系统的虚拟内存管理器有时会设置一堆虚拟内存表,这些表基本上说“此内存由以下磁盘扇区支持”。在检索已写入交换文件且必须读回的数据时,它使用非常相似的过程。唯一的区别在于内存和磁盘同步的积极程度,到特定磁盘扇区的映射是静态的还是动态的(尽管即使对于“真实”文件,磁盘扇区也可能在您运行时发生变化,例如,在写入写入时复制文件系统时),无论是必须写入(交换)还是可以简单地删除内存(mmap-ed 文件w/o 脏页)在内存压力下,等等。

涉及的虚拟内存地址转换有几层,因 CPU 和操作系统而异,因此确切的机制有所不同,但基本思想是,在mmaping 之后,您绕过目录结构并以忽略的方式与底层磁盘扇区交互名称和路径之类的东西。

于 2016-09-16T18:27:28.073 回答