进程组ID是如何设置的?

进程组ID是如何设置的?

我读到会话的ID与通过系统调用创建会话的进程的pid相同setsid(),但我没有找到任何有关如何设置进程组ID的信息。进程组ID与创建该进程组的进程的pid是否相同?

答案1

一般来说,是的,进程组 ID 等于创建进程组的进程的进程 ID,并且该进程通过将自己放入组中来创建进程组。

setpgid您可以在系统调用及其变体的文档中找到此信息setpgrp。 BSD 和 System V 之间的细节历史上有所不同。最常见的用例是:

  • 进程将自己放入自己的进程组中,新的PGID等于PID。这可以使用 SysVsetpgrp()或 with 来完成setpgid(0, 0),其中任何一个都0可以被显式替换getpid()
    请注意,虽然过程将自己放入组中,实际上,这通常是由启动器(shell 或守护进程监视器)在执行之前完成的程序fork,即它是由子进程之间和execve子进程中的启动器中的代码完成的。
  • 进程将自身放入同一会话中的现有进程组中。 Shell 对管道执行此操作:为了在自己的进程组中运行foo | bar,Shell 通常会执行以下操作:

    1. 设置管道。
    2. 分叉一个进程。子进程将自己放入自己的进程组中G,关闭管道的读取端并将写入端移动到 stdout,然后执行foo
    3. 分叉一个进程。子进程将自己放入现有的进程组中G,关闭管道的写入端并将红色端移至标准输入,然后执行bar.

    对 的调用setpgid可以在父进程中而不是在子进程中执行,或者除了子进程之外还可以在父进程中执行。两者都这样做可以避免出现竞争条件,以防第二个子级的初始化超过第一个子级的初始化。

  • 具有作业控制功能的 shell 通常在其自己的进程组中运行。但在退出或挂起之前,它会返回到其原始进程组(即,它将自身放回启动它的进程组,假设该组仍然存在)。

POSIX 规范setpgid描述了这些用例。它进一步解释了没有什么其他方法可以保证有效。特别是,虽然旧的 BSD 系统允许进程加入不同会话中的进程组或组成新的 PGID,但在大多数现代系统(包括现代 BSD)上情况并非如此。

相关内容