首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >while循环中fork()中的fork()

while循环中fork()中的fork()
EN

Stack Overflow用户
提问于 2015-05-06 14:13:58
回答 1查看 693关注 0票数 3

请考虑在这里查看我的代码。我的计划是我有一个while循环。在while循环中,我执行了一条for语句。在for循环之后,我使用fork。现在我有了一个家长和一个child1。在parent内部,我执行了另一个fork,给了我一个parent和child2。现在我的问题是:

1)为什么在成功时,fork1 x=3会打印两次?

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

3)对于x=1,我认为输出真的搞混了,比如为什么在发送1和发送2之间打印"child1 pid=4783“。fork 1也打印了两次。

请帮我解决这些问题。我一直在看帖子,但我似乎看不到类似的问题。我还能错过什么呢?非常感谢!下面是我的代码片段:

代码语言:javascript
复制
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--;
}

以及以下结果:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2015-06-26 05:05:48

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

代码语言:javascript
复制
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的状态

代码语言:javascript
复制
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);

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

代码语言:javascript
复制
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=8267
[3] child2 pid=8268
[3] child1 exiting
[3] process ID 8267 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] fork2 successful
[2] process ID 8268 returned status 9.This is NOT an exit status, so I will keep looping....
[2] fork1 successful
[2] child1 pid=8270
[2] child2 pid=8271
[2] child1 exiting
[2] process ID 8270 returned status 0.
[2] Child1 ran. Child2 killed.

x=1
[1] SENDING 0
[1] SENDING 1
[1] SENDING 2
[1] fork1 successful
[1] RECEIVING 3
[1] fork1 successful
[1] child1 pid=8273
[1] fork2 successful
[1] process ID 8271 returned status 9.This is NOT an exit status, so I will keep looping....
[1] child2 pid=8274
[1] child1 exiting
[1] process ID 8273 returned status 0.
[1] Child1 ran. Child2 killed.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30068906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档