在 fork() 之后卡在 wait()

Stuck on wait() after fork()

我看了一些关于这个的话题,但没能解决 -

我分叉了两次,但是在等待最后一个过程时它卡在了 wait() 上,如果我删除 wait() 它会继续,但显然它不会等待:

相关代码如下:

  /*Fork #1*/
  if((pid=fork())==0)
  {
    if(command -> inputRedirect != NULL)
    {
      fclose(stdin);
      fopen(command -> inputRedirect,"r");
    }
    fclose(stdout);
    dup(pipefd[1]);
    close(pipefd[1]);
    i=execvp(command->arguments[0],command->arguments);
  }
  if(i == -1)
  {
    perror("Error");
    return 1;
  }
  printf("\nParent: %d , Child: %d\n",getpid(),pid);

  command = command->next;
  /*Fork #2*/
  if((pid=fork())==0)
  {

    fclose(stdin);
    dup(pipefd[0]);
    close(pipefd[0]);

    if(command -> outputRedirect != NULL)
    {
      fclose(stdout);
      fopen(command ->outputRedirect,"w");
    }

    i=execvp(command->arguments[0],command->arguments);
    _exit(0);
  }

  if(i == -1)
  {
    perror("Error");
    return 1;
  }

  if(command->blocking == 1)
  {
    int test=0;
    printf("\nParent: %d , Child: %d\n",getpid(),pid);
    printf("\ntest1\n");
    while((test=wait(NULL)) != pid)
    {
      printf("\n %d \n ", test);
    }
    printf("\ntest2\n");
  }
  return 0;
}

我添加了一些测试来查看一些 PID 输出以及内部发生了什么,它等待第一个 chil 进程完成,并打印正确的 ID,但在第二个上它只是阻塞。

但是我确实在屏幕上看到第二个进程已完成(从进程输出)。

欢迎就此主题提供任何帮助。

谢谢。

进程在没有未收集的children时调用wait()是错误的(wait()将return-1并设置errnoECHILD ),所以 wait() 挂起的事实表明 一个 child 进程集。一旦 child 进程实际上已经终止——包括如果它在 wait() 调用之前已经终止——parent 进程就可以进行调度并且应该 return 立即从wait()。因此,wait() 调用挂起是一个很好的迹象,表明两个 child 进程之一实际上还没有退出。

正如我在评论中所写,child 的输出不一定是它是否已退出的可靠指示。 child退出时会变成僵尸,直到被收集为止,可以在table.

进程中查看

您的文件描述符处理看起来有点奇怪,这可能是您问题的根源。首先,如果你想将管道 FD 复制到 children 的标准流上,那么你应该使用 dup2() 来明确指定,而不是 close() + dup().不过,更可能是您的实际问题是 parent 进程未能关闭其管道 FD 的副本。如果第二个 child 正在等待其标准输入(来自管道)上的 EOF,那么 parent 未能关闭其管道写入端的副本将阻止 child 从终止。