5

我是“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);
 }
为什么输出看起来像::
子地址::804a01c
父地址::804a01c

为什么父母和孩子的地址都相同?

4

3 回答 3

9

有两个不同的内存位置分配给它们的变量和函数。

没有; Linux 实现了虚拟内存,这意味着每个进程都有自己完整的地址空间。结果,在 a 之后fork,两个进程看到它们的内存对象副本的相同地址。

(顺便说一句:VM 还会导致代码在物理内存中的进程之间共享,并且所有数据只会在写入时被复制。)

于 2012-03-15T16:58:34.327 回答
3

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

于 2012-03-15T16:58:51.220 回答
2

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

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

于 2012-03-15T17:01:08.883 回答