概念
信号是事件发生时对进程的通知机制,也被称为软中断。大多数情况下,无法预测信号到达的精确时间。
一个(具有合适权限的)进程能够向另一进程发送信号。进程也可以向自身发送信号。然而,发往进程的诸多信号,通常有源于内核。引发内核为进程产生信号的各类事件如下。
- 硬件异常,即硬件检测到一个错误条件并通知内核,内核发送相应信号给相关进程。例如除0,或者访问非法内存区域。
- 用户输入了特殊字符,例如中断字符(ctrl+C)、暂停字符(ctrl+Z)。
- 软件事件。例如定时器到期,进程执行的CPU时间超限,或者该进程的某个子进程退出。
信号的传递及处理
信号产生后,会于稍后被传递给某一进程,而进程也会采取某些措施来响应信号。在产生和到达期间,信号处于等待(pending)状态。
通常,一旦内核接下来要调度该进程运行,等待信号会马上送达;如果进程正在运行,则会立即传递信号。
然而,有时需要确保一段代码不被传递来的信号所中断,可以将信号添加到进程的信号掩码中。如果所产生的信号属于阻塞之列,那么信号将保持等待状态,直至稍后对其解除阻塞(从信号掩码中移除)。
信号到达后,可执行如下默认操作之一。
- 忽略信号
- 终止(杀死)进程:这有时是指进程异常终止,而不是进程因调用exit()而发生的正常终止。
- 产生核心转储文件,同时进程终止:核心转储文件包含对进程虚拟内存的镜像,可将其加载到调试器中以检查进程终止时的状态。
- 停止进程:暂停进程的执行。
- 恢复之前暂停的进程,继续执行。
也可以对信号做处理:
- 采取默认行为
- 忽略信号
- 执行信号处理器程序
注意,无法将信号处置设置为终止进程或者转储核心(除非这是对信号的默认处置)。效果最接近的是调用exit()或者abort()。abort()函数为进程产生一个SIGABRT信号,该信号将引发进程转储核心文件并终止。
linux可以查看/proc/PID/status来看信号的处理:
SigQ: 1/62839
SigPnd: 0000000000000000 \\基于线程的等待信号
ShdPnd: 0000000000010000 \\进程级等待信号
SigBlk: 0000000000010000 \\阻塞信号
SigIgn: 0000000000000006 \\忽略信号
SigCgt: 0000000000000000 \\捕获信号