fork循环中的fork()内的fork()

时间:2015-05-06 06:13:58

标签: c for-loop while-loop fork

请考虑在此处查看我的代码。我的计划是我有一个while循环。在while循环中我执行for语句。在for循环之后,我使用fork。现在我有一个父母和一个child1。在父母内部,我执行另一个分叉,给我一个父母和child2。现在我的问题是:

1)为什么在x=3时,“fork1 success”语句打印两次?

2)对于x=2x=3出现了同样的问题。它说fork 1和fork 2成功但没有输入child1child2。它跳过了n=waitpid(-1, &status, 0);行,然后继续打印n,然后是x--并转到x=1;

3)对于x = 1,我认为输出真的混淆了,就像为什么在SENDING 1和SENDING 2之间打印了“child1 pid = 4783”。第1页也再次打印了两次。

请帮我解决这些问题。我一直在阅读帖子,但我似乎无法看到类似的问题。我有什么可能错过的?非常感谢! 以下是我的代码片段:

while(x>0)
{
    printf("x=%d\n", x);
    for(i=0; i<3; i++)
    {
        printf("SENDING %d\n", i);
    }

    pid1=fork();
    printf("fork1 successful\n");
    if(pid1>0)
    {
        printf("RECEIVING %d\n", i);
        pid2=fork();
        if(pid2>0)
        {
            printf("fork2 successful\n");
            n=waitpid(-1, &status, 0);
            printf("%d\n", n);

            if(n==pid1) //sleep done
            {
                kill(pid2, SIGKILL);
                printf("Child1 ran. Child2 killed.\n\n");
            }

            else if(n==pid2) //scanf received               
            {
                kill(pid1, SIGKILL);
                printf("Child2 ran. Child1 killed.\n\n");
            }
        }    
        else
        {
            printf("child2 pid=%d\n", getpid());            
            scanf("%d", &y);
            exit(1);
        }
    }
    else
    {
        printf("child1 pid=%d\n", getpid());
        sleep(5);
        exit(0);
    }
x--;
}

以下结果:

x=3

SENDING 0

SENDING 1

SENDING 2

fork1 successful

RECEIVING 3

fork1 successful

child1 pid=4781

fork2 successful

child2 pid=4782

4781

Child1 ran. Child2 killed.

x=2

SENDING 0

SENDING 1

SENDING 2

fork1 successful

RECEIVING 3

fork1 successful

fork2 successful

4782

x=1

SENDING 0

SENDING 1

child1 pid=4783

SENDING 2

fork1 successful

RECEIVING 3

child2 pid=4784

fork2 successful

child2 pid=4786

fork1 successful

child1 pid=4785

1

4784

1 个答案:

答案 0 :(得分:1)

我相信你假设n=waitpid(-1, &status, 0)会暂停,直到其中一个子进程完成。 waitpid将在任何子进程发生任何更改后返回。如果将变量“x”添加到print语句中,并添加一个语句以显示waitpid的状态返回值,则可以在第二个循环中看到x=2,{{1语句由前一个循环进程之一的终止信号触发。这里的事情变得更加混乱 - 因为流程可能会抢先一步。在原始代码中,您可以看到两个显示x = 1的child1进程。

waitpid

解决此问题的一种方法是检查x=3 [3] SENDING 0 [3] SENDING 1 [3] SENDING 2 [3] fork1 successful [3] RECEIVING 3 [3] fork2 successful [3] fork1 successful [3] child1 pid=8166 [3] child2 pid=8167 [3] child1 exiting [3] process ID 8166 returned status 0.[3] Child1 ran. Child2 killed. x=2 [2] SENDING 0 [2] SENDING 1 [2] SENDING 2 [2] fork1 successful [2] RECEIVING 3 [2] fork1 successful [2] fork2 successful [2] process ID 8167 returned status 9.x=1 [1] SENDING 0 [1] SENDING 1 [1] SENDING 2 [2] child1 pid=8171 [2] child2 pid=8172 [1] fork1 successful [1] RECEIVING 3 [1] fork1 successful [1] child1 pid=8173 [1] fork2 successful [1] child2 pid=8174 [2] child1 exiting [1] child1 exiting [1] process ID 8171 returned status 0 的状态:

waitpid

然后我相信你得到了预期的结果:

do
{
  n=waitpid(-1, &status, 0);
  printf("[%d] process ID %d returned status %d.", x, n, status);
  if (WIFEXITED(status)==0)
     printf("This is NOT an exit status, so I will keep looping....\n");
  else
     printf("\n");

 } while (WIFEXITED(status)==0);