【问题标题】:wait() does not wait for every childwait() 不会等待每个孩子
【发布时间】:2015-10-13 16:45:05
【问题描述】:

我有一个创建“n”个子进程的循环。这些进程进入一个单独的程序并休眠“x”秒,然后返回退出状态“x”。问题是当我尝试等待每个单独的进程时。似乎我的 wait() 调用等待最后一个进程,然后程序退出。我想要这样,无论哪个孩子退出,我都可以打印他们的信息,然后等待下一个孩子退出并打印他们的信息......等等。

代码:

int main()
{
      char input[12];
      int n, i, ch;
      pid_t pid;
      int status={0};

      printf("Enter an integer: ");
      fgets(input, 12, stdin);
      if (input[10] == '\n' && input[11] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
      rmnewline(input);

      n = atoi(input);

      for(i=0; i<=n-1; i++)
      {
      pid = fork();
      if(pid == 0)
        execl("/home/andrew/USP_ASG2/sleep", "sleep", NULL);
      }

      for(i=0; i<=n-1; i++)
      {
        wait(&status);
        if(WIFEXITED(status))
        {
          int exitstat = WEXITSTATUS(status);
          printf("Child %d is dead with exit status %d\n", pid, exitstat);
        }
      }
}

输出:

In child 15930
In child 15929
In child 15928
Child 15930 is dead with exit status 5
Child 15930 is dead with exit status 5
Child 15930 is dead with exit status 5

【问题讨论】:

  • 顺便说一句:就风格而言,i&lt;=n-1 会比i&lt;n 更清晰
  • @WeatherVane 否。由于数组偏移量从零开始,for ( i = 0; i &lt; n; i++ ) 是在 C 中编写 for 循环的规范方法。只需谷歌“c for loop”。查看许多示例:codingunit.com/…stackoverflow.com/questions/4604500/…tutorialspoint.com/cprogramming/c_for_loop.htmthegeekstuff.com/2012/12/c-loops-examples 此外,省略减法可能会略微提高性能,尤其是在 x86 等寄存器匮乏的架构上。
  • @AndrewHenle 你确定你正确阅读了我的评论吗?如果n==0,循环控制i&lt;=n-1 在未签名时可能会发疯。我写的是“clearer as”,而不是“clearer than”。
  • @WeatherVane 我似乎确实误读了您的评论。我应该认识到这一点。是的,i &lt; n 会更清楚。好吧,我们意见一致。

标签: c parent-child wait exit-code waitpid


【解决方案1】:

您忘记捕获wait() 的返回值,因此pid 仍然包含您分叉的最后一个进程的pid。

这样做:

pid = wait(&status);

你会得到预期的输出。

【讨论】:

  • 感谢您的澄清!尽管所有孩子仍然以相同的“随机”退出状态同时退出。编辑:我目前正在更改随机数种子的生成方式,因为这可能是问题所在。
  • @AndrewRicci 当您fork() 时,子进程独立于父进程和任何其他子进程运行。它们都是由操作系统单独安排的,因此如果不使用管道、信号或共享内存互斥,您将无法控制每个结束的时间。退出值完全取决于子进程。
  • 他们执行的程序用 'srand(time(NULL));' 生成一个随机数然后它在 0 到 9 之间随机休眠。它不能控制它只是它们都应该在不同的时间退出。
  • @AndrewRicci time() 函数返回自纪元以来的当前时间(以秒为单位)。由于您的循环快速连续地执行所有分叉,因此子进程很可能在同一秒内启动。这意味着它们将使用相同的种子,因此都会生成相同的随机数并休眠相同的时间。
  • 更改了种子(改为 srand(getpid()))。糟糕的种子,但它确实改变了退出的时间。谢谢你!
猜你喜欢
  • 2012-09-10
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多