我是“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
为什么父母和孩子的地址都是一样的?
3 回答
不; Linux实现了virtual memory,这意味着每个进程都有自己的完整地址空间 . 因此,在
fork
之后,两个进程都会查看其内存中对象副本的相同地址 .(顺便说一句:VM还会导致代码在物理内存中的进程之间共享,并且所有数据都只是copied-on-write . )
地址是进程本地的 .
804a01c
在一个进程中与另一个进程中的804a01c
不同 .由于virtual memory:两个地址空间看起来都与各个进程相同 . 存储的物理内存是不同的 . 然而,实际上,通过内存优化(由大多数内核实现)使相应的不同虚拟页面映射到相同的物理页面,直到其中一个进程写入该内存页面,此时页面被物理复制 . 到另一个物理地址(并为该进程重新映射虚拟页面) .
还有许多其他复杂情况:最受认可的是
fork()
的返回值在进程之间有所不同,尽管这通常是寄存器值的差异,而不是内存 . 但是,打开文件和其他一些资源可以标记为不可继承,因此可能存在其他差异 - 次要但有时很有用 .