有人可以帮助我理解系统如何处理在进程进行fork()
调用之前设置的变量。下面是我写的一个小测试程序,试图了解幕后发生的事情。
据我所知,在分叉时,进程的当前状态是“克隆”,包括变量。我的想法是,如果我在调用fork之前选择了一个2D数组,我需要在父进程和子进程中释放数组。
从示例代码下面的结果中可以看出,这两个值的作用就好像它们彼此完全分离,但它们具有完全相同的地址空间。我预计无论首先完成哪个进程,tmp的最终结果都是-4
。
我是C和Linux的新手,有人可以解释一下这是可能的吗?也许变量tmp成为指向每个进程中不同的指针的指针?非常感谢。
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int tmp = 1;
pid_t forkReturn= fork();
if(!forkReturn) {
/*child*/
tmp=tmp+5;
printf("Value for child %d\n",tmp);
printf("Address for child %p\n",&tmp);
}
else if(forkReturn > 0){
/*parent*/
tmp=tmp-10;
printf("Value for parent %d\n",tmp);
printf("Address for parent %p\n",&tmp);
}
else {
/*Error calling fork*/
printf("Error calling fork);
}
return 0;
}
标准结果:
Value for child 6
Address for child 0xbfb478d8
Value for parent -9
Address for parent 0xbfb478d8
答案 0 :(得分:2)
它确实复制了整个地址空间,并且更改子进程中的内存不会影响父进程。理解这一点的关键是要记住指针只能指向你自己的进程中的某个东西,并且副本发生在较低的级别。
但是,你不应该在fork的子代中调用malloc()或free()。这可能会死锁(当你调用fork()时,另一个线程在malloc()中)。唯一能安全呼叫孩子的功能是那些也被认为对信号处理人员安全的功能。我以前只有在编写多线程代码时才能声称这是真的。但Apple非常友好地在标准库中生成后台线程,因此死锁始终是真实的。绝不允许fork的子节点从if块中删除。调用_exit以确保它没有。