10 Signal
这篇笔记介绍lecture16、17中的内容。
进程组
每个进程都属于且仅属于一个进程组。进程组编号由一个正整数(process group ID)标记。默认情况下,子进程与父进程有相同的进程组。
// return process group PID
pid_t getpgrp(void);
getpgrp() 函数获取进程的进程组PID。
// return 0 on success, -1 on error
pid_t setpgid(pid_t pid, pid_t pgid);
setpgid() 函数更改 pid 进程的进程组PID为 pgid 。如果 pid 为0,则使用当前进程的PID;如果 pgid 为0,则由 pid 指定的进程PID为 pgid 。
作业(job)是unix shell使用的抽象,用于表示进程,作为评估单个命令行的结果而创建的进程。任何时候最多有一个前台作业和零或多个后台作业。shell会为每个作业创建一个单独的进程组(进程组ID通常取自作业中一个父进程)。

信号
信号是一种消息,通知操作系统某种类型的事件发生。这里的类型对应某种系统事件。系统事件分为硬件事件和软件事件。

要将信号传递给目标进程,需要发送信号、接受信号两个步骤。
通过更新目标进程上下文中的某些state,内核向目标进程发送信号。有两种情况会导致发送信号:内核检测到系统事件,或进程调用了一个 kill 函数。
// pid - receiver process, sig - signal
// 0 if OK, -1 on error
int kill(pid_t pid, int sig);
内核会迫使目标进程对信号做出反应。进程可以忽略信号、终止,或者通过一个用户级别的名为信号处理器的程序捕获信号。
待处理信号(pending signal)指已发送但尚未接收的信号。任何时候,每个类型最多只有一个待处理信号。如果某个进程已经有了类型k的待处理信号,接下来发送到进程的类型k信号会被简单地丢弃。
进程可以选择性地阻止某些信号。被阻止的信号可以发送到目标进程,但在阻塞解除之前,这些待处理信号不会被接受。
对于每个进程,内核在待处理位向量(pending bit vector)中维护待处理信号,在阻塞位向量(blocked bit vector)中维护阻塞信号。在发送类型k的信号时,内核设置类型k的位;在接受类型k的信号时,内核清除类型k的位。