做叉子时有趣的父母和孩子的行为

时间:2012-11-11 20:52:35

标签: c operating-system fork

有人可以解释下面程序的输出。为什么我和父母和孩子都得到相同的& 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;
}

1 个答案:

答案 0 :(得分:10)

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

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

  

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

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

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

[顺便说一句,你无法使用%d可靠地打印内存地址(这恰好适用于32位x86)。请改用%p。此外,fork的返回类型为pid_t,而不是int。]