2

有人可以解释下面程序的输出吗?为什么我为父母和孩子获得相同的 &a 值。

它们必须具有不同的物理地址。如果我认为我正在获取虚拟地址,那么它们如何具有相同的虚拟地址,因为据我所知,每个物理地址都唯一地绑定到虚拟地址。

#include <stdio.h>
#include <stdlib.h>
int main(void) {


    int pid=fork();
      int a=10;
    if(pid==0)
        {
            a=a+5;
            printf("%d %d\n",a,&a);
        }
        else
        {
            a=a-5;
            printf("%d %d\n",a,&a);
        }
        return 0;
}
4

1 回答 1

10

子进程从父进程继承其虚拟地址空间,即使子进程写入页面后虚拟地址开始引用不同的物理地址。这称为写时复制 (CoW) 语义。

所以,在父级&a中被映射到一些物理地址。Fork 最初只是复制映射。然后,当进程写入 时a,CoW 启动并在子进程中,a复制保存的物理页面,更新虚拟地址映射以引用副本,并且两个进程都有自己的副本a,在相同的虚拟地址&a但在不同的物理地址。

每个物理地址都唯一绑定到虚拟地址

这不是真的。物理内存地址可能未映射,也可能映射到一个或多个进程地址空间中的多个虚拟地址。

相反,一个虚拟地址可以映射到多个物理地址,只要这些虚拟地址存在于不同进程的虚拟地址空间中。

[顺便说一句,您不能可靠地打印内存地址%d(恰好在 32 位 x86 上工作)。改为使用%p。此外,返回类型forkpid_t,而不是int。]

于 2012-11-11T20:55:38.177 回答