【问题标题】:Difference between the address space of parent process and its child process in Linux?Linux中父进程和子进程地址空间的区别?
【发布时间】:2011-01-04 13:51:07
【问题描述】:

我对某事感到困惑。我已经读过,当父进程创建子进程时,子进程会获得其父进程地址空间的副本。抄袭是什么意思? 如果我使用下面的代码,那么它会为孩子和父母的堆上的变量“a”打印相同的值。那么这里发生了什么?

int main ()
{
        pid_t pid;
        int *a = (int *)malloc(4);
        printf ("heap pointer %p\n", a);
        pid = fork();
        if (pid < 0) {
                fprintf (stderr, "Fork Failed");
                exit(-1);
        }
        else if (pid == 0) {
                printf ("Child\n");
                printf ("in child heap pointer %p\n", a);
        }
        else {

                wait (NULL);
                printf ("Child Complete\n");
                printf ("in parent heap pointer %p\n", a);
                exit(0);
        }
}

【问题讨论】:

  • 请注意,在父项和子项中,您都打印变量a地址。您打印变量a,(它是指针类型)。
  • 你看到喜欢的答案了吗?

标签: c linux fork


【解决方案1】:

子级获得父级地址空间的精确副本,在许多情况下,其布局可能与父级地址空间相同。我必须指出,每个人都有自己的内存虚拟地址空间,这样每个人都可以在相同的地址拥有相同的数据,但在不同的地址空间。此外,linux 在创建子进程时使用写时复制。这意味着父和子将共享父地址空间,直到其中一个进行写入,此时内存将物理复制到子。这消除了execing 新进程时不需要的副本。既然你只是要用新的可执行文件覆盖内存,为什么还要复制它呢?

【讨论】:

    【解决方案2】:

    是的,您将获得相同的虚拟地址,但请记住每个都有自己的进程虚拟地址空间。 直到有一个 Copy-On-Write 操作完成,一切都是共享的。 因此,当您尝试 strcpy 或任何写入操作时,会发生 Copy-On-Write,这意味着指针 a 的子进程虚拟地址将为子进程更新,但不会为父进程更新。

    【讨论】:

      【解决方案3】:

      副本的意思就是,虚拟地址空间的位相同的副本。出于所有意图和目的,这两个副本是无法区分的,直到您开始写入其中一个(更改在另一个副本中不可见)。

      【讨论】:

        【解决方案4】:

        使用fork(),子进程接收到一个新的地址空间,其中复制了父地址空间的所有内容(实际上,现代内核使用copy-on-write)。

        这意味着如果你在一个进程中修改a或它所指向的值,另一个进程仍然看到旧值。

        【讨论】:

          【解决方案5】:

          你得到了两个堆,由于内存地址被转换到物理内存的不同部分,它们都有相同的虚拟内存地址。

          【讨论】:

            猜你喜欢
            • 2014-07-28
            • 1970-01-01
            • 1970-01-01
            • 2011-09-29
            • 1970-01-01
            • 1970-01-01
            • 2015-06-08
            相关资源
            最近更新 更多