Fork()父和子

时间:2014-04-16 17:05:38

标签: c process fork parent-child

我需要的是有3个孩子和1个父母(主程序)因为孩子和父母将具有不同的功能。 我不知道为什么我不能正确地做到这一点,据我所知,当你做fork()时,如果它返回0,你执行孩子的代码和父母&# 39;否则代码。 所以,这是我的计划:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char ** argv) {

   printf ("Init Parent. PID =%d\n", getpid());

   fork();
   fork();
   if (fork() == 0) {
   printf ("Init Child. PID =%d\n", getpid());
    sleep(1);

   } else {        
    printf ("I am the parent. PID = %d\n",getpid()); 
    sleep(1);

   }
    exit(0);
}

这是输出:

Init Parent. PID =9007
I am the parent. PID = 9007
I am the parent. PID = 9009
Init Child. PID =9010
Init Child. PID =9011
I am the parent. PID = 9008
I am the parent. PID = 9012
Init Child. PID =9013
Init Child. PID =9014

这就是我想要的:

Init Parent. PID =9007
I am the parent. PID = 9007
Init Child. PID =9010
Init Child. PID =9011
Init Child. PID =9013
Init Child. PID =9014

我不知道为什么它说我是父母3次以及如何正确地做,因为1

if (fork() == 0) 

看起来很糟糕。

我真的很感激任何帮助,谢谢你。

3 个答案:

答案 0 :(得分:0)

更改以下代码。

你需要检查每个fork()它的返回码,而不仅仅是最后一次fork的调用。我没有跑步和尝试,但这是我感觉到的错误。 你说 - 你需要1个父母和3个孩子 - 所以在第一个fork()期间 - 将创建1个孩子,然后创建第二个fork() - 将创建1个孩子的孙子和1个父母的孩子。

修改

      parent
       /   \  
   fork-1  fork-2
      |      |
    child1  child-2
      |
    fork-2
      |
    child3 


for(int i=0;i<2;i++)
{
   if (fork()==0)
      printf ("Init Child. PID =%d\n", getpid());
      sleep(1);
   } else {
      printf ("I am the parent. PID = %d\n",getpid()); 
      sleep(1);
   }
}

答案 1 :(得分:0)

fork复制调用它的进程,创建一个处于完全相同状态并继续在同一点运行的新(子)进程。父和子之间的唯一区别是fork调用返回的内容。

请考虑您的代码会发生什么。你从一个过程开始:

printf ("Init Parent. PID =%d\n", getpid());

以便一个进程打印一条消息

fork();

你分叉,所以现在有两个进程(父和子)

fork();

这两个进程都是fork,所以你现在有4个进程(父进程,2个子进程和孙子进程)

if (fork() == 0) {

再次分叉,所以你现在有8个进程 - 父进程,3个子进程,3个孙子进程和一个曾孙。他们中的一半(一个孩子,两个孙子和曾孙)从这个叉子返回0,因为他们是第三个叉子创建的孩子。另一半是父母。

所以在这3个分支之后,你有8个进程,其中4个将打印&#34; Init Child&#34;其中4个将打印&#34;我是父母&#34;

如果你只想要3个直接孩子(而且没有孙子女),你需要安排你的代码,这样孩子们就不会再打电话了。你可以使用类似的东西:

if (fork() && fork() && fork())
    printf ("I am the parent. PID = %d\n",getpid());
else
    printf ("Init Child. PID =%d\n", getpid());

答案 2 :(得分:0)

您必须在第一次分叉后检查父母。 每次时间,您致电fork()您正在产生一个孩子。你现在正在做的是:

  • 开始执行1个程序(+1 proc,1 proc total)
  • 首先fork():主程序产生子项(+1 proc,总共2个proc)
  • 第二个fork():子主程序产生子项。 (+2触发,总共4次触发)
  • 第三个fork()所有处理前面提到的spawn子项(+4个procs,总共8个proc)。

原始代码生成的流程树如下所示:

      pi
    /  |  \
   pi  pi  pi
  / |  |  
 pi pi pi
 |
 pi

可能的解决方案(适用于n个孩子):

int noProcs = 3;
int i;
for (i = 0; i < noProcs; ++i) {
  if (fork() == 0) {
    printf("in child\n");
    //Do stuff...
    exit(0);
   }
 }
 //DONT FORGET: Reap zombies using wait()/waitpid()/SIGCHLD etc...

请注意,每次fork()次调用后,生成的子项都会执行相同的后续代码。对于循环迭代中的每个步骤,我在fork()生成一个孩子后会发生什么:

  • 子进程:执行子代码,并调用exit()。这可以防止我们循环并创建比预期更多的孩子。
  • 父进程:绕过if(fork() == 0)语句的正文并逐步完成循环,按指定生成其他子进程。