【发布时间】:2012-04-21 12:36:34
【问题描述】:
我们知道页表是用来从虚拟内存页地址中获取物理内存页地址的。但是,内核如何知道一个物理内存页面是否由不同的进程共享(例如在分叉进程及其父进程的情况下)。这样的清单保存在哪里?
【问题讨论】:
我们知道页表是用来从虚拟内存页地址中获取物理内存页地址的。但是,内核如何知道一个物理内存页面是否由不同的进程共享(例如在分叉进程及其父进程的情况下)。这样的清单保存在哪里?
【问题讨论】:
内核是创建所有虚拟映射的实体。所以它确切地知道什么是共享的,什么不是。如果没有内核的帮助,用户空间进程无法创建共享映射。
当进程请求分叉时,内核还负责复制映射。它包含所需的所有信息。
一个页面的映射数量保存在代表该页面的struct page 结构中的一个字段中。每次创建新映射时它都会增加,而当映射消失时它会减少。
如果你想更深入地研究这个,你可以访问Linux-MM。特别是,请阅读文档部分中链接(免费提供的 PDF)Mel Gorman 的 Understanding the Linux Virtual Memory Manager 书(非常技术性)。
【讨论】:
引用自CSAPP 3rd,Linux 内核进程的虚拟内存视图
pgd,它指向一级页表(页全局目录)的基础,mmap,它指向一个 vm_area_structs(区域结构)的列表,每一个都表征一个当前虚拟地址空间的区域。当内核运行这个进程时,它会将pgd存储在CR3控制寄存器中。
当当前进程调用fork函数时,内核会为新进程创建各种数据结构并为其分配一个唯一的PID。要为新进程创建虚拟内存,它会创建当前进程的 mm_struct、区域结构和页表的精确副本。它将两个进程中的每个页面标记为只读,并将两个进程中的每个区域结构标记为写时私有复制。
【讨论】: