我对fork()如何从父进程复制内存感到困惑 . 我试着通过写一个例子找到它:
int global_var = 0;
int main(int argc, char* argv[]){
int local_var = 1;
pid_t child;
child = fork();
if (child < 0){
cout << "Fork error: " << strerror(errno) << endl;
return 1;
}
if (child != 0 ){ // parent
cout << "Parent: global address: " << &global_var << endl;
cout << "Parent: local address: " << &local_var << endl;
++global_var;
++local_var;
cout << "Parent: global: " << global_var << endl;
cout << "Parent: local: " << local_var << endl;
}else{
cout << "Child: global address: " << &global_var << endl;
cout << "Child: local address: " << &local_var << endl;
sleep(1);
cout << "Child: global: " << global_var << endl;
cout << "Child: local: " << local_var << endl;
}
return 0;
}
我看到了结果:
父级:全局地址:0x6021a0父级:本地地址:0x7fff942dd99c父级:全局:1父级:本地:2子级:全局地址:0x6021a0子级:本地地址:0x7fff942dd99c子级:全局:0子级:本地:1
为什么孩子没有看到变量的变化,即使孩子的变量与父母的变量在同一地址 . 请有人帮我解释一下 .
提前致谢 .
3 回答
孩子和父母不共享记忆 . 地址具有相同的值,但它们位于不同的堆栈中,如两个不同城市的"123 Main Street";它们指的是记忆中的两个不同位置 . 孩子看不到父母做出的改变,因为这些改变没有发生在孩子的堆叠中 .
当你分叉一个进程时,它就变成了自己的程序,即父进程的副本 .
在您的示例代码中,您只需在父进程中增加global_var和local_var .
试试这个看 .
希望这会有所帮助,叉子有时会令人困惑 .
进程有两种类型的虚拟内存:内核和用户 . fork()时,创建一个具有单独虚拟内存的克隆子进程,该进程几乎与父进程相同 . fork()调用在父级中进行,但返回两次,一次在父级中,一次在子级中 . 案例由返回码区分:
除了此返回代码之外,用户存储器将是相同的 . 内核内存有一些区别:计时器在孩子中休息,pid和ppid是不同的等等 . 通常调用execve()来跟进子进程,这将覆盖用户区域并允许子进程执行与父母完全不同的代码 . execve()被调用一次并且永远不会返回,因为代码是过时的,例如,