03-传递、处置及处理的特殊情况
22.2 传递、处置及处理的特殊情况
本节讨论了针对特定信号,适用于其传递、处置以及处理方面的特殊规则。
SIGKILL和SIGSTOP
SIGKILL信号的默认行为是终止一个进程,SIGSTOP信号的默认行为是停止一个进程,二者的默认行为均无法改变。当试图用signal()和sigaction()来改变对这些信号的处置时,将总是返回错误。同样,也不能将这两个信号阻塞。这是一个深思熟虑的设计决定。不允许修改这些信号的默认行为,这也意味着总是可以利用这些信号来杀死或者停止一个失控进程。
SIGCONT和停止信号
如前所述,可使用SIGCONT信号来使某些(因接收SIGSTOP、SIGTSTP、SIGTTIN和 SIGTTOU信号而)处于停止状态的进程得以继续运行。由于这些停止信号具有独特目的,所以在某些情况下内核对它们的处理方式将有别于其他信号。
如果一个进程处于停止状态,那么一个SIGCONT信号的到来总是会促使其恢复运行,即使该进程正在阻塞或者忽略SIGCONT信号。该特性之所以必要,是因为如果要恢复这些处于停止状态的进程,舍此之外别无他法。(如果处于停止状态的进程正在阻塞SIGCONT信号,并且已经为SIGCONT信号建立了处理器函数,那么在进程恢复运行后,只有当取消了对SIGCONT的阻塞时,进程才会去调用相应的处理器函数。)
如果有任一其他信号发送给了一个已经停止的进程,那么在进程收到SIGCONT信号而恢复运行之前,信号实际上并未传递。SIGKILL信号则属于例外,因为该信号总是会杀死进程,即使进程目前处于停止状态。
每当进程收到SIGCONT信号时,会将处于等待状态的停止信号丢弃(即进程根本不知道这些信号)。相反,如果任何停止信号传递给了进程,那么进程将自动丢弃任何处于等待状态的SIGCONT信号。之所以采取这些步骤,意在防止之前发送的一个停止信号会在随后撤销SIGCONT信号的行为,反之亦然。
由终端产生的信号若已被忽略,则不应改变其信号处置
如果程序在执行时发现,已将对由终端产生信号的处置置为了SIG_IGN(忽略),那么程序通常不应试图去改变信号处置。这并非系统的硬性规定,而是编写应用程序时所应遵循的惯例,34.7.3节将解释其理由。与之相关的信号有:SIGHUP、SIGINT、SIGQUIT、SIGTTIN、SIGTTOU和SIGTSTP。