进程组由一个或多个共享同一进程组标识符(PGID)的进程组成。进程组 ID 是一个数字,其类型与进程 ID 一样(pid_t)。

   **一个进程组拥有一个进程组首进程,该进程是创建该组的进程,其进程 ID 为该进程组的 ID,新进程会继承其父进程所属的进程组 ID**。

   进程组拥有一个**生命周期**,其**开始时间为首进程创建组的时刻,结束时间为最后一个成

员进程退出组的时刻**。一个进程可能会因为终止而退出进程组,也可能会因为加入了另外一 个进程组而退出进程组。进程组首进程无需是最后一个离开进程组的成员。

   **会话是一组进程组的集合**。进程的会话成员关系是由其会话标识符(`SID`)确定的,会话

标识符与进程组 ID 一样,是一个类型为 pid_t 的数字。

   **会话首进程是创建该新会话的进程,其进程 ID 会成为会话 ID。新进程会继承其父进程的会话 ID。**

    **一个会话中的所有进程共享单个控制终端。**控制终端会在会话首进程首次打开一个终端

设备时被建立。一个终端最多可能会成为一个会话的控制终端。

    **在任一时刻,会话中的其中一个进程组会成为终端的前台进程组,其他进程组会成为后

台进程组。只有前台进程组中的进程才能从控制终端中读取输入。**当用户在控制终端中输入 其中一个信号生成终端字符之后,该信号会被发送到前台进程组中的所有成员。

    这些字符包括生成 `SIGINT` 的中断字符(通常是 `Control-C`)、生成 `SIGQUIT` 的退出字符(通常是 `Control-\\`)、生成 `SIGSTP` 的挂起字符(通常是 `Control-Z`)。

   当到控制终端的连接建立起来(即打开)之后,**会话首进程会成为该终端的控制进程。**成

为控制进程的主要标志当断开与终端之间的连接时内核会向该进程发送一个 SIGHUP 信号。

在窗口环境中,控制终端是一个伪终端。每个终端窗口都有一个独立的会话,窗口的 启动 shell 是会话首进程和终端的控制进程。

$ echo $$
400
$ find / 2> /dev/null | wc -l &   # 创建后台进程
[1] 659
$ sort < longlist | uniq -c    # 前台进程

Untitled

SIGHUP信号

    当一个控制进程失去其终端连接之后,内核会向其发送一个 `SIGHUP` 信号来通知它这一

事实,还会发送一个SIGCONT 信号以确保当该进程之前被一个信号停止时重新开始该进程。

一般来讲,这种情况可能会在下面两个场景中出现: