Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用fork时如何映射内存?_C_Linux_Fork_Address Space - Fatal编程技术网

C 使用fork时如何映射内存?

C 使用fork时如何映射内存?,c,linux,fork,address-space,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

我不熟悉“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);
 }
#包括
int i=10;
int-pid;
int main(){
如果((pid=fork())==0){
i++;//在我读到的某个地方,当需要写入时,会为child创建单独的内存空间
printf(“父地址=%p\n”,&i);//这应该从父内存空间返回地址
}否则{
i++;
i++;
printf(“子地址=%p\n,&i);//这应该返回子内存空间的地址
}
等待(0);
返回(0);
}
为什么输出看起来像:: 子地址::804a01c 父地址::804a01c 为什么父母和孩子的地址都一样

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

#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);
 }
没有;Linux实现,这意味着每个进程都有自己的完整地址空间。因此,在一个
fork
之后,两个进程都会看到其内存对象副本的相同地址


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

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

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


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

它们最好是相同的。您希望指针在两个pro中以相同的方式引用内存访问(即使两个内存块是不同的)。阅读有关虚拟内存的内容,这将回答您的问题。请注意,
i
的值在父级和子级之间是不同的,即使两个副本都存储在同一虚拟地址。“一旁”事实上非常重要:当子进程生成时,没有任何内容被真正复制。这将是一个巨大的性能损失,因为在Unix上经常发生分叉(实际上每次生成新进程时)。精确的机制依赖于“页面错误”。如果您感兴趣,您可能会想了解它们。好的,那么我们如何获得该var的实际地址而不是虚拟地址?(询问只是为了满足我的好奇心)@buch11:我想你不能,但我会让专家确认。无论如何,你不应该。这种信息只被内核知道,它只允许你访问进程本地地址。这就是所谓的“受保护内存”。每个进程只能访问自己的内存。@buch11如果您想进一步搜索,您几乎是在问MMU是如何工作的。只有内核知道与给定虚拟地址对应的物理地址。用户模式程序无法轻松检测到它正在有MMU的系统上运行。