我对此感到困惑。我已经读到,当父进程创建子进程时,子进程会获得其父进程的地址空间的副本。复制在这里意味着什么?如果我在下面使用代码,那么它将在所有情况下都在堆上打印变量“ a”的相同地址。即在孩子和父母的情况下。那么这里发生了什么?
int main() { pid_t pid; int * a =(int *)malloc(4); printf(“堆指针%p \ n”,a); pid = fork(); 如果(pid <0){ fprintf(stderr,“叉失败”); 退出(-1); } 否则(pid == 0){ printf(“ Child \ n”); printf(“在子堆指针%p \ n中,a); } 其他{ wait (NULL); printf ("Child Complete\n"); printf ("in parent heap pointer %p\n", a); exit(0); }
}
子级将获得父级地址空间的精确副本,在许多情况下,该副本可能以与父级地址空间相同的格式进行布局。我必须指出,每个内存都有自己的虚拟地址空间,因此每个内存可以在相同地址但在不同地址空间中拥有相同数据。另外,Linux在创建子进程时使用写时复制。这意味着父级和子级将共享父级地址空间,直到其中之一进行写操作为止,此时,内存将被物理复制到子级。这样可以消除exec进行新处理时不需要的副本。由于您将要使用新的可执行文件覆盖内存,因此为什么要复制它呢?
exec