【问题标题】:Interesting parent and child behavior while doing fork做叉子时有趣的父母和孩子行为
【发布时间】:2012-10-31 09:11:02
【问题描述】:

谁能解释一下下面程序的输出。为什么我的 &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;
}

【问题讨论】:

    标签: c operating-system fork


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 这是一个很好的答案,但我认为您应该更清楚地说明 virtual:physical 映射是 M:N ——不仅可以将相同的物理地址映射到多个虚拟地址(一个或多个地址空间),同一个虚拟地址可以映射到多个物理地址(当然每个地址空间不能超过一个这样的映射)。后者似乎是这里的混淆点。
    猜你喜欢
    • 2017-07-25
    • 2021-10-17
    • 2018-01-29
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2017-09-08
    相关资源
    最近更新 更多