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

Dev*_*yal 2 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;
}
Run Code Online (Sandbox Code Playgroud)

Fre*_*Foo 10

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

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

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

这不是真的.物理存储器地址可以是未映射的,或者可以映射到一个或多个进程的地址空间中的多个虚拟地址.

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

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

  • 这是一个很好的答案,但我认为您应该更清楚虚拟:物理映射是M:N - 不仅可以将相同的物理地址映射到多个虚拟地址(在一个或多个地址空间中),相同的*虚拟*地址可以映射到多个*物理*地址(但当然每个地址空间不超过一个这样的映射).后者似乎是这里的混乱点. (2认同)