Linux中父进程与其子进程地址空间的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4594329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between the address space of parent process and its child process in Linux?
提问by abs
I am confused about it. I have read that when a child is created by a parent process, child gets a copy of its parent's address space. What it means here by copy? If i use code below, then it prints same addresses of variable 'a' which is on heap in all cases. i.e in case of child and parent. So what is happening here?
我对此感到困惑。我读过当一个子进程由父进程创建时,子进程会获得其父进程地址空间的副本。这里的副本是什么意思?如果我使用下面的代码,那么它会打印在所有情况下都在堆上的变量“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); }
}
}
采纳答案by Robert S. Barnes
The child gets an exact copy of the parents address space, which in many cases is likely to be laid out in the same format as the parent address space. I have to point out that each one will have it's own virtual address space for it's memory, such that each could have the same data at the same address, yet in different address spaces. Also, linux uses copy on write when creating child processes. This means that the parent and child will share the parent address space until one of them does a write, at which point the memory will be physically copied to the child. This eliminates unneeded copies when exec
ing a new process. Since you're just going to overwrite the memory with a new executable, why bother copying it?
子进程获得父地址空间的精确副本,在许多情况下,它可能以与父地址空间相同的格式进行布局。我必须指出,每个人都将拥有自己的内存虚拟地址空间,这样每个人都可以在相同的地址但在不同的地址空间中拥有相同的数据。此外,linux 在创建子进程时使用写时复制。这意味着父级和子级将共享父级地址空间,直到其中之一进行写入,此时内存将物理复制到子级。这在exec
执行新进程时消除了不需要的副本。既然你只是要用一个新的可执行文件覆盖内存,为什么还要复制它呢?
回答by Oliver Charlesworth
A copy means exactly that, a bit-identical copy of the virtualaddress space. For all intents and purposes, the two copies are indistinguishable, until you start writing to one (the changes are not visible in the other copy).
副本的确切含义是虚拟地址空间的位相同副本。出于所有意图和目的,两个副本是无法区分的,直到您开始写入其中一个(更改在另一个副本中不可见)。
回答by Giuseppe Ottaviano
With fork()
the child process receives a new address space where all the contents of the parent address space are copied (actually, modern kernels use copy-on-write).
随着fork()
子进程接收如果母公司地址空间的所有内容都复制一个新的地址空间(实际上,现代的内核使用写入时复制)。
This means that if you modify a
or the value pointed by it in a process, the other process still sees the old value.
这意味着如果您a
在一个进程中修改或它指向的值,另一个进程仍然会看到旧值。
回答by daramarak
You get two heaps, and since the memory addresses are translated to different parts of physical memory, both of them have the same virtual memory address.
您将获得两个堆,并且由于内存地址被转换为物理内存的不同部分,因此它们具有相同的虚拟内存地址。
回答by rstalekar
Yes, you will get the same virtual address, but remember each one has it's own process virtual address spaces. Till there is a Copy-On-Write operation done everything is shared. So when you try to strcpy or any write operation the Copy-On-Write takes place which means the child process virtual address of pointer a will be updated for the child process, but not so for the parent process.
是的,您将获得相同的虚拟地址,但请记住,每个虚拟地址都有自己的进程虚拟地址空间。直到有一个 Copy-On-Write 操作完成,一切都是共享的。因此,当您尝试执行 strcpy 或任何写入操作时,会发生 Copy-On-Write,这意味着子进程将更新指针 a 的子进程虚拟地址,但不会为父进程更新。