4

假设我在 Linux 中有一个进程,从中我有fork()另一个相同的进程。在forking 之后,由于原始进程将开始写入内存,Linux的写时复制机制将赋予该进程唯一的物理内存页,该物理内存页与分叉进程使用的内存页不同。

在执行的某个时刻,我如何知道原始进程的哪些页面已被写入时复制?

我不想使用 SIGSEGV 信号处理程序并在一开始就授予对所有页面的只读访问权限,因为这会导致我不想要的开销。

4

2 回答 2

3

跟踪系统调用 - fork()、clone():

copy_process()->copy_mm()->dup_mm()->dup_mmap()-->在这里你会发现VMA通过VMA将它们标记为“写时复制”的算法:

http://www.cs.columbia.edu/~krj/os/lectures/L17-LinuxPaging.pdf

http://www.cs.columbia.edu/~junfeng/13fa-w4118/lectures/l20-adv-mm.pdf

本质上(请参阅幻灯片),如果 PTE 不可写(基于硬件),并且 VMA 被标记为可写(基于软件) - 这意味着内存是写时复制的。

你总是可以编写一个内核模块来做到这一点。

于 2016-04-11T04:04:15.897 回答
0

你可能不得不接受一些开销。

如果您有特权,您可以预读 /proc/self/pagemap(64 位,偏移量 8*(addr / PAGE_SIZE))来获取 PFN(它是低 54 位)。然后在 /proc/kpagecount 中查找该 PFN 以查看该页面是否已共享。

如果没有权限,可以在父子的pagemap中对比PFN。

您可以通过将 Pss(比例集大小)与 /proc/smaps 中的总大小进行比较来判断映射中的任何页面是否共享。

于 2012-06-02T04:48:55.727 回答