【发布时间】:2015-12-26 12:35:37
【问题描述】:
您好,我一直在开发一个 fork 孩子的程序,然后会从每个孩子那里派生更多的孩子,但这不是我需要帮助的。当我运行我的程序时(在这里它是一个函数但工作方式相同)我应该有一个父级(PPID)产生 3 个子级(PIDS = 1,2,3)但我得到的是相同的 PID 和 PPID 3 次(我当前的代码)或在我得到 3 个父母之前,每个父母都有一个孩子,并且 PPIDS 和 PIDS 都不同,但 PPID 与以前的孩子 PID 相同。在我最近的尝试中,它永远不会在孩子(儿子)上方显示父母(爸爸)消息。它应该是这样的
[dad] hi am I PID 1234 and I come from ####(dont care what this number is)
[son] hi i am PID 1111 and I come from PPID 1234
[son] hi i am PID 1112 and I come from PPID 1234
[son] hi i am PID 1113 and I come from PPID 1234
这是我的代码。如果可能的话,我只是在寻找提示,除非这只是我犯的一个愚蠢的错误,比如“哦,只需将 fork() 移动到子进程”或类似的东西。
我还有一个 child_count,以便我可以轻松地数孩子。
int forking(null)
{
void about(char *);
int i=0;
int j=0;
int child_count =0;
about("dad");
for(i = 0; i < 3; i++ ){
pid_t child = 0;
child = fork();
if (child < 0) { //unable to fork error
perror ("Unable to fork");
exit(-1);}
else if (child == 0){ //child process
about ("son");
printf("I am child #%d \n",child_count);
child_count++;
exit(0);}
else { //parent process (do nothing)
}
}
for(j = 0; j < 3; j++ ){
wait(NULL);//wait for parent to acknowledge child process
}
return 0;
}
【问题讨论】:
-
要记住两件事:第一是一旦你分叉,子进程会得到父进程内存的副本,当子进程修改时,例如variables 这些变量仅在孩子中更改,父母(或任何“兄弟姐妹”)不会看到这些变量更改。第二件事是您在
else案例中调用wait将阻止父和子。 -
哦,您的代码中有一个不好的未定义行为。您定义了
child变量,然后在初始化它之前 使用它。未初始化的局部变量有一个 indeterminate 值,在没有初始化的情况下使用它们会导致 UB。你可能想考虑一下你在哪里打电话给fork。 -
哦,你的意思是像 pid_t child =0?你是什么意思 wait() 阻止父母和孩子?关于内存副本,您能给我一个示例代码吗?这样更容易看出这一点。
-
关于
wait,你在调用fork之后无条件地调用它,所以它会在父进程和子进程中被调用。如果您将child初始化为零,代码将在您的条件下采用什么路径?并且进程不共享内存,进程中的内存仅用于该进程,并且该内存包含child_count之类的变量,因此在一个进程中修改变量不会导致在任何其他进程中对其进行修改。再次,想想你在哪里做或应该做fork电话。 -
最后的
while循环需要是for(i=0;i<3;i++)循环。如果你在while循环的主体中放置一个printf,你会发现它永远不会运行,因为i由于前面的for循环已经是3。