【问题标题】:How does wait() work in Linux?wait() 在 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

预期输出:

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

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

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

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

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

请问我哪里出错了?

【问题讨论】:

    标签: linux process


    【解决方案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)”测试时。
    • 谢谢!在完全混乱中完全错过了! :)
    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 2010-11-07
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 2012-01-03
    • 1970-01-01
    相关资源
    最近更新 更多