char *p = (char*) mmap(...);
....; /* check if p is not -1 */
a = *p;
运行最后一个语句时,会发生页面错误。内核中的错误处理程序将在物理内存中分配一个页面,并将文件中的4K字节复制到该页面中,然后修改页面条目。读取*p
的指令将再次成功执行,这次成功。
但是故障处理程序如何知道与页面关联的文件名和路径。文件名(或fd
)在哪里存储?以及文件中的偏移量。
如果进程的数据段中的页面被换出(我想是交换文件)怎么办?内核如何知道何时需要在以后交换页面时从哪里复制?
答案 0 :(得分:0)
处理程序不知道文件名或路径,因为它没有使用它们(你可以说,因为即使在创建映射后从文件系统中删除了文件,映射继续正常工作;文件内容保持有效,直到所有打开的文件描述符和内存映射都关闭。)
它也没有使用fd
;在close
调用之后,您被允许fd
mmap
传递给mmap
,并且映射仍然有效(这在某些系统上是必要的低ulimit
s用于打开文件句柄;您可以一次映射10,000个文件,但如果fds的fd
为1000,则无法为所有文件保留开放ulimit
)。
在mmap
时,操作系统的虚拟内存管理器会设置一堆虚拟内存表,基本上说是“#34;这个内存由以下磁盘扇区支持"”。它在检索已写入交换文件的数据时使用了一个非常类似的过程,必须重新读回。唯一的区别在于内存和磁盘的同步程度,是否映射到特定磁盘扇区是静态的还是动态的(虽然即使对于"真实的文件,磁盘扇区也可能在运行时发生变化,例如,当写入写入时复制文件系统时),是否必须写入(交换)内存或者只是在内存压力等情况下丢弃(mmap
- ed文件,没有脏页面)
有几层虚拟内存地址转换因CPU和操作系统而异,所以确切的机制不同,但基本的想法是在mmap
之后,你绕过目录结构和以忽略名称和路径等内容的方式与底层磁盘扇区交互。