使用fork时如何映射内存?

时间:2012-03-15 16:56:27

标签: c linux fork address-space

我是" 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 个答案:

答案 0 :(得分:8)

  

将两个不同的记忆位置分配给他们的变量和功能。

都能跟得上; Linux实现virtual memory,意味着每个进程都有自己的完整地址空间。因此,在fork之后,两个进程都会看到内存对象副本的相同地址。

(顺便说一句:VM还会导致代码在物理内存中的进程之间共享,所有数据都只有copied-on-write。)

答案 1 :(得分:2)

地址是流程本地的。一个流程中的804a01c与另一个流程中的804a01c不同。

答案 2 :(得分:2)

由于virtual memory:两个地址空间看起来都与各个进程相同。存储的物理内存是不同的。然而,实际上,通过内存优化(由大多数内核实现)使相应的不同虚拟页面映射到相同的物理页面,直到其中一个进程写入该内存页面,此时页面被物理复制。到另一个物理地址(并为该过程重新映射虚拟页面)。

还有许多其他复杂情况:最受认可的是fork()的返回值在进程之间有所不同,尽管这通常是寄存器值的差异,而不是内存。但是,打开文件和其他一些资源可以标记为不可继承,因此可能存在其他差异 - 次要但有时很有用。