【问题标题】:Fork(), wait for all child process to finish vs wait for one child to finishfork(),等待所有子进程完成 vs 等待一个子进程完成
【发布时间】:2018-06-19 03:00:34
【问题描述】:

我不明白应该在哪里使用 wait(NULL) 或 while(pid = wait(&status))>0)。我很困惑,我得到了奇怪的结果,请帮忙!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (int argc, char *argv[]) {
   pid_t childpid = 0; 
   int i, n;

   if (argc != 2){   /* check for valid number of command-line arguments */ 
      fprintf(stderr, "Usage: %s processes\n", argv[0]);
      return 1; 
   }     
   n = atoi(argv[1]);  
   for (i = 1; i < n; i++)
      if ((childpid = fork()) <= 0)
         break;

   fprintf(stderr, "i:%d  process ID:%ld  parent ID:%ld  child ID:%ld\n",
           i, (long)getpid(), (long)getppid(), (long)childpid);
   return 0; 
}
  1. 您将如何修改此代码,以便原始进程在所有子进程都退出后打印出其信息?

  2. 您将如何修改此代码,以便进程在其子进程退出后打印其信息?

【问题讨论】:

    标签: c fork parent-child wait


    【解决方案1】:

    相同的修改可以完成这两项工作。

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    int main (int argc, char *argv[])
    {
        pid_t childpid = 0; 
        int i, n;
    
        if (argc != 2)
        {   /* check for valid number of command-line arguments */ 
            fprintf(stderr, "Usage: %s processes\n", argv[0]);
            return 1; 
        } 
        n = atoi(argv[1]);  
        for (i = 1; i < n; i++)
        {
            if ((childpid = fork()) <= 0)
                break;
        }
    
        int corpse;
        int status;
    
        while ((corpse = wait(&status)) > 0)
        {
            fprintf(stderr, "%d: child %d exited with status 0x%.4X\n",
                   (int)getpid(), corpse, status);
        }
    
        fprintf(stderr, "i:%d  process ID:%ld  parent ID:%ld  child ID:%ld\n",
                i, (long)getpid(), (long)getppid(), (long)childpid);
        return 0; 
    }
    

    当子进程执行wait() 时,它会立即失败,因为没有要等待的孙子进程。因此,孩子在“它的孩子”(全部为零)退出后打印其输出。

    当父进程执行wait() 循环时,它会在信息可用时报告每个子进程,然后打印自己的信息。

    一般来说你有不止一个孩子,所以第二个问题有点含糊。但是,如果您希望它等待一个孩子(并且您不在乎哪个孩子),那么请从 wait() 周围删除循环。如果您关心哪个孩子,请使用waitpid() 而不仅仅是wait()

    您可以通过在子进程中返回i 或从i 计算的数字来使输出更有趣。请注意,在 forking 循环从 1 而不是 0 运行之前,如果您在命令行中指定 4,您将获得 3 个子进程以及原始父进程。

    【讨论】:

    • 很难说清楚为什么,但很大程度上取决于调度、机器上的内核数量以及诸如此类的事情。另一种可能性是你没有重新编译成功——不太可能,但发生了更有趣的事情。每个孩子都会报告自己的数据;唯一的问题是他们报告的顺序,以及命令行提示符是否已经出现(如果你从 shell 运行它;如果你在 GUI 中运行它,你可能只会看到这些行出现 - 和可能会消失)。
    猜你喜欢
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 2011-06-26
    • 2013-02-13
    • 2015-05-27
    • 2022-01-23
    • 2010-11-06
    相关资源
    最近更新 更多