wait() 在 Linux 中是如何工作的?

Posted

技术标签:

【中文标题】wait() 在 Linux 中是如何工作的?【英文标题】:How does wait() work in Linux? 【发布时间】:2014-10-29 17:11:44 【问题描述】:

谁能解释一下为什么输出是这样的?我对这些进程的执行方式(按什么顺序?)以及waitpid()/wait() 感到非常困惑。 代码如下:

#include<stdio.h>
main()

    int pid1, pid2, pid3;
    pid1=fork();
    if(pid1 == 0)
        printf("PID of child 1 is :%d\n",getpid());
        //sleep(2);
    
    pid2=fork();
    if(pid2  == 0)
        printf("PID of child 2 is :%d\n",getpid());
        //sleep(2);
    
    pid3=fork();
    if(pid3  == 0)
        printf("PID of child 3 is :%d\n",getpid());
        //sleep(2);
    
    else
        printf("PID of parent is :%d\n",getpid());
        waitpid(pid1,0,0);
        waitpid(pid2,0,0);
        waitpid(pid3,0,0);
    

实际输出:

PID of child 1 is :4963

PID of parent is :4962

PID of parent is :4963

PID of child 2 is :4966

PID of parent is :4966

PID of child 2 is :4964

PID of parent is :4964

PID of child 3 is :4967

PID of child 3 is :4965

PID of child 3 is :4969

PID of child 3 is :4968

预期输出:

    父母的PID,因为pid1不是0,这里永远不会是0。

    然后等到 pid1 即 child1 被终止并打印 child 1 的 PID

    那么现在 child2 和 child3 还没有分叉,所以它们被跳过了

    然后是父母的PID,child1的pid,child2的pid

    然后是父母的PID,child1的pid,child2的pid和child3的pid。

请问我哪里出错了?

【问题讨论】:

【参考方案1】:

我们开始...

pid1=fork()

此时有两个进程正在进行。父级 [PID 4962] 和刚刚生成的子级 [PID 4963]。父母有 pid1 = 4963 [孩子的 PID],孩子 [child1] 有 pid1 = 0。所以,孩子会打印出来:

"PID of child 1 is: 4963"

这两个过程都在愉快地进行,直到它们到达:

pid2=fork()

这里,父 [PID 4962] 和 child1 [PID 4963] 都产生了一个子进程。我们将调用原始父级产生的孩子 child2 [可能是 PID 4964] 和 child1 产生的孩子,我们将调用 child1_1 [可能是 PID 4966]。现在,原来的父母有 pid2 = 4964 [也许],child2 的 pid2 = 0。child1 的 pid2 = 4966 [也许],child1_1 的 pid2 = 0。因此,child2 和 child1_1 都会打印出一些东西:

"PID of child 2 is: 4966"
"PID of child 2 is: 4964"

现在,所有这些过程都达到了这一点:

pid3=fork()

哎哟。

原来的父进程、child1、child2 和 child1_1 都产生了一个子进程。你什么 最终结果是这样的:

对于原始父级、child1、child2 和 child1_1,pid3 != 0 对于他们的四个子进程,pid3 == 0

所以,这四个子进程都这样报告它们的 PID:

"PID of child 3 is: xxxx"

但原来的父 [4962]、child1 [4963]、child2 [可能是 4964] 和 child1_1 [可能是 4966] 打印:

"PID of parent is: xxxx"

然后等待其 PID 为 pid1、pid2 和 pid3 的子进程返回。

请记住,所有这些进程都是同时运行的,这就解释了 为什么你不一定能预测打印语句的顺序 进行。

【讨论】:

您好,非常感谢您的耐心等待!一切都很好,除了我还有一个疑问,在这里,请不要介意。当遇到 pid2 时它有两个父母,所以它打印了“父母的 pid 是”2 次,但是当遇到 pid3 时,为什么它不打印“父母的 pid 是”4 次,虽然它有 4 个父母? 我认为混淆在你的 else 子句的范围内。如果您仔细检查代码中的花括号,您会发现 else 子句仅与“if (pid3 == 0)”相结合。所以,事实上,四个终极父母正在打印出他们自己的 PID……但只有在他们未能通过“if (pid3 == 0)”测试时。 谢谢!在完全混乱中完全错过了! :)

以上是关于wait() 在 Linux 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

我在工作中是如何使用Linux的

微服务在实践中是如何工作的?

组合在 Hibernate 中是如何工作的?

reduce() 方法在 Java 8 中是如何工作的?

闭包在方法 mapValues 中是如何工作的?

继承在 Ruby 中是如何工作的?