使用 fork() 生成进程树

Generating a process tree with fork()

我需要创建一个进程树,其关系如图所示。

问题是我必须按字母顺序创建所有“节点”。我已经走到这一步了,但我的订单并不一致。我相信我使用 waitpid 不正确?

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char **argv)
{
  pid_t pidA, pidB, pidC, pidD, pidE, pidF, pidG, pidI;

  pidA = fork();
  if (pidA < 0)
  {
    perror("A");
    exit(1);
  }
  else if (pidA == 0)
  {
    printf("%d: A\n", getpid());

    pidB = fork();
    if (pidB < 0)
    {
      perror("B");
      exit(1);
    }
    else if (pidB == 0)
    {
      printf("%d: B\n", getpid());
      waitpid(pidD, NULL, 0);

      pidE = fork();
      if (pidE < 0)
      {
        perror("E");
        exit(1);
      }
      else if (pidE == 0)
      {
        printf("%d: E\n", getpid());
        waitpid(pidG, NULL, 0);

        pidI = fork();
        if (pidI < 0)
        {
          perror("E");
          exit(1);
        }
        else if (pidI == 0)
        {
          printf("%d: I\n", getpid());
        }
        else
        {
          ;
        }
      }
      else
      {
        pidF = fork();
        if (pidF < 0)
        {
          perror("F");
          exit(1);
        }
        else if (pidF == 0)
        {
          printf("%d: F\n", getpid());
        }
        else
        {
          ;
        }
      }
    }
    else
    {
      pidC = fork();
      if (pidC < 0)
      {
        perror("B");
        exit(1);
      }
      else if (pidC == 0)
      {
        printf("%d: C\n", getpid());
        waitpid(pidF, NULL, 0); // !

        pidG = fork();
        if (pidG < 0)
        {
          perror("G");
          exit(1);
        }
        else if (pidG == 0)
        {
          printf("%d: G\n", getpid());
        }
        else
        {
          ;
        }
      }
      else
      {
        pidD = fork();
        if (pidD < 0)
        {
          perror("B");
          exit(1);
        }
        else if (pidD == 0)
        {
          printf("%d: D\n", getpid());
        }
        else
        {
          ;
        }
      }
    }
  }
  else
  {
    ;
  }

  return 0;
}

输出不一致,所以我认为这部分帮助不大。

5644: A
5645: B
5646: C
5647: D
5648: G
5650: F
5649: E
5651: I

这里的主要问题是 waitpid 仅当所有进程线性相关(即父进程、子进程、“孙子”进程等)时才足以同步。

但是,如图所示,您的过程不是线性相关的。当您从 B 进程中调用 waitpid(pidD, NULL, 0); 时,您会看到出现此问题。不仅 pidD 没有在此上下文中定义,而且 D 进程也不是 B 进程的子进程,因此 waitpid 是不合适的。

@EOF 提出了一个很好的观点,即尝试 运行 串联多个进程会破坏拥有多个进程的目的。然而,如果你只是想把这个练习当作一个有趣的脑筋急转弯来做,我建议在原来的进程中设置 pipes ,然后在适当的进程想要发出它已经退出的信号时关闭写入端。正在等待第一个进程结束的进程可以在读取端调用select