【问题标题】:How to use wait(); in a process in order to wait for its child processed to be executed first如何使用等待();在一个进程中为了等待它的子进程首先被执行
【发布时间】:2019-05-16 16:02:43
【问题描述】:

每个printf 命令代表一个进程。 p0 进程应等待 p2 进程执行,而 p2 应等待至少 2 个子进程 (p3,p4,p5) 先执行:

```
    #include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h>
#include <sys/wait.h>
#define _POSIX_SOURCE
int main()
{
    int pid1, pid2, pid3, pid4, pid5;
    int i;
    int status;

    pid1=fork();

    if (pid1 != 0){
      wait(&status);
    printf("I'm the parent P0.PID=%d, PPID=%d.\n", getpid(), getppid());}
else{

     printf("I'm the child P1 my parent is P0. PID=%d, PPID=%d.\n", getpid(), getppid());


    pid2=fork();

    if (pid2!=0){

    printf("I'm the child P2 and parent to p3,p4,p5.PID=%d, PPID=%d.\n", getpid(), getppid());



    pid3=fork();
    if (pid3 == 0){
    printf("I'm the child P3.PID=%d, PPID=%d.\n", getpid(), getppid());
}
    else {

        pid4=fork();
        if(pid4 == 0)
        {
    printf("I'm the child P4.PID=%d, PPID=%d.\n", getpid(), getppid());
}  else{
            pid5 = fork();
            if(pid5 == 0)
        {
    printf("I'm the child P5.PID=%d, PPID=%d.\n", getpid(), getppid());
              }
           }
        }
     }
  }
    /*  
    if(getppid(&pid1)==getppid(&pid5)){

        execl("/bin/ps","ps","-f",(char *)NULL);
    }*/
return 0;
  }

              P0
           /      \  
         P1        P2
                 / | \
                P3 P4 P5

【问题讨论】:

  • P0 在分叉 P2 之前调用 wait()。它只在等待 P1。
  • @JohnBollinger 你好,我刚接触堆栈溢出(我什至不知道基础知识)。再次感谢您帮助我。
  • 您需要在if(pid5==0) 中添加一个else 块,在循环中调用wait() 以等待2 个孩子。
  • @barmar 谢谢,我太糟糕了,至少我在努力。
  • 请注意,如果输出不是到 tty(例如,如果您运行此程序时将输出重定向到文件),您将看到一些您可能认为奇怪的行为(行被打印多次)。

标签: c linux parent-child pid


【解决方案1】:

首先,为与“if (pid4==0)”关联的else 使用大括号括起来的块,并确保将“if (pid5==0)”块嵌套在其中。这为您提供了更好的内部一致性,但更重要的是,它避免了在从不设置它的过程中测试 pid5 的值:

                else {
                    pid5=fork();
                    if (pid5==0){
                        printf("I'm the child P5.PID=%d, PPID=%d.\n", getpid(), getppid()); 
                    }
                }

然后,如果您将else 块添加到最内层嵌套的if,它将仅由进程2 进入。那么,在这样的块中,您可以插入两个对wait() 的调用以收集两个孩子.

另请注意,紧跟在if (pid!=0){ 之后的wait() 似乎放错了位置。它由 p0p1 是它派生的唯一孩子时调用。因此,它会导致 p0 等待 p1,而您声明的意图是等待 p2,而那时还没有分叉。您表示根本不需要等待p1。对p2 的等待可以进入与if (pid2==0) 关联的else 块中。

但也请注意,由于它想专门等待 p2p0 必须避免在它收集 p1 的可能事件中被愚弄强>第一。您可以通过检查 wait() 的返回值(成功时是收集的孩子的 pid)来正确处理它,或者您可以改用 waitpid() 来专门等待进程 p2 和没有其他的。

【讨论】:

  • 感谢您的大力帮助,我修复了 p0 父进程,因此它将在 p2 之后执行,但我认为 p2 应该在其至少 2 个子进程 (p3,p4,p5) 获得后执行首先执行(不能这样做)。新输出不应该是:p3、p4、p5 或其中的 2 个,然后是 p2,然后是 p0?我能做到吗?我将在上面发布新代码。我还尝试在 --> if (pid3==0) 和 if (pid4==0) 之后添加 2 个 wait() 命令,但它不起作用我认为 1 个或多个等待命令应该放在 pid2==0 所以p2 会等待它的孩子(不确定)。
  • @rnduser21,如果进程 p2 启动了一些子进程,然后等待它们,那么它会在 之前和 之后运行。我已经回答了你应该如何设置它。要使其仅在等待的子进程之后执行打印,请将其 printf() 调用放在其 wait() 调用之后(在只有该进程运行的代码中)。
  • pidwait 绝对什么都不做。除了在 p1 之后删除错位等待意味着 p1 将在 p2 之前执行,无论我尝试什么(包括添加到与 pid2 关联的 else 块)。也可以通过添加 2 wait();在 printf 之后调用我没有取得任何成果。
猜你喜欢
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多