我是" fork()"的新手,我到处读到当调用fork()时,启动了当前(调用)进程的精确副本。现在,当我运行以下代码时,那里应该是两个不同的过程,将两个不同的内存位置分配给它们的变量和函数。
#include<stdio.h>
int i=10;
int pid;
int main(){
if((pid=fork())==0){
i++;//somewhere I read that separate memory space for child is created when write is needed
printf("parent address= %p\n",&i);// this should return the address from parent's memory space
}else{
i++;
i++;
printf("child address= %p\n",&i);// this should return the address of child's memory space
}
wait(0);
return(0);
}
Why The output looks like:: child address::804a01c parent address::804a01c
为什么父母和孩子的地址都相同?
答案 0 :(得分:8)
将两个不同的记忆位置分配给他们的变量和功能。
都能跟得上; Linux实现virtual memory,意味着每个进程都有自己的完整地址空间。因此,在fork
之后,两个进程都会看到内存对象副本的相同地址。
(顺便说一句:VM还会导致代码在物理内存中的进程之间共享,所有数据都只有copied-on-write。)
答案 1 :(得分:2)
地址是流程本地的。一个流程中的804a01c
与另一个流程中的804a01c
不同。
答案 2 :(得分:2)
由于virtual memory:两个地址空间看起来都与各个进程相同。存储的物理内存是不同的。然而,实际上,通过内存优化(由大多数内核实现)使相应的不同虚拟页面映射到相同的物理页面,直到其中一个进程写入该内存页面,此时页面被物理复制。到另一个物理地址(并为该过程重新映射虚拟页面)。
还有许多其他复杂情况:最受认可的是fork()
的返回值在进程之间有所不同,尽管这通常是寄存器值的差异,而不是内存。但是,打开文件和其他一些资源可以标记为不可继承,因此可能存在其他差异 - 次要但有时很有用。