进程信号



信号Signals
是Unix系统 使用的最古老的 进程间通信 的方法之一
操作系统通过信号来通知进程系统中发生了某种预先规定好的事件 一组事件中的一个)
也是 用户进程 之间通信和同步的一种原始机制
一个键盘中断或者一个错误条件 比如进程试图访问它的虚拟内存中不存在的位置等)都有可能产生一个信号
Shell也使用信号向它的子进程发送作业控制信号

信号 在 Unix System V 中首先引入 它实现了15种信号 但很不可靠 BSD4.2 解决了其中的许多问题 而在BSD4.3中进一步加强和改善了信号机制 但两者的接口不完全兼容
在Posix 1003.1标准中做了 强行规定 它定义了一个标准的信号接口 但没有规定接口的实现 目前几乎所有 Unix 变种都提供了 和 Posix标准兼容的信号实现机制

阶段
在一个信号的生命周期中有两个阶段
生成和传送 当一个事件发生时 需要通知一个进程 这时生成一个信号 当进程识别出信号的到来 就采取适当的动作来传送或处理信号
在信号到来和进程对信号进行处理之间 信号在进程上挂起 pending)

内核为进程生产信号 来响应不同的事件 这些事件就是 信号源

主要的信号源如下
异常      进程运行过程中出现异常
其它进程 一个进程可以向另一个或一组进程发送信号
终端中断 Ctrl-C Ctrl-\等
作业控制 前台、后台进程的管理
分配额   CPU超时或文件大小突破限制
通知     通知进程某事件发生 如I/O就绪等
报警     计时器到期

常见信号
SIGHUP   从终端上发出的结束信号
SIGINT   来自键盘的中断信号 Ctrl-C)
SIGQUIT  来自键盘的退出信号 Ctrl-\)
SIGFPE   浮点异常信号 例如浮点运算溢出)
SIGKILL  该信号结束接收信号的进程
SIGALRM  进程的定时器到期时 发送该信号
SIGTERM  kill 命令发出的信号
SIGCHLD  标识子进程停止或结束的信号

每一个信号都有一个缺省动作 它是当进程没有给这个信号指定处理程序时 内核对信号的处理

有5种缺省的动作
异常终止 abort 在进程的当前目录下 把进程的地址空间内容 寄存器内容保存到一个叫做 core 的文件中 而后终止进程
退出 exit 不产生core文件 直接终止进程
忽略 ignore 忽略该信号
停止 stop 挂起该进程
继续 continue 如果进程被挂起 则恢复进程的运行 否则 忽略信号

进程 可以对任何信号指定另一个动作或重载缺省动作 指定的新动作可以是忽略信号
进程 可以暂时地阻塞一个信号 因此进程可以选择对某种信号所采取的特定操作

这些操作包括
忽略信号 进程可忽略产生的信号 但 SIGKILL 和 SIGSTOP 信号不能被忽略,必须处理 由进程自己或由内核处理) 进程可以忽略掉系统产生的大多数信号
阻塞信号 进程可选择阻塞某些信号 即先将到来的某些信号记录下来 等到以后 解除阻塞后)再处理它

由进程处理该信号 进程本身可在系统中注册处理信号的处理程序地址 当发出该信号时 由注册的处理程序处理信号
由内核进行缺省处理 信号由内核的缺省处理程序处理 执行该信号的缺省动作 例如 进程接收到SIGFPE 浮点异常)的缺省动作是产生core并退出 大多数情况下 信号由内核处理
对信号的任何处理 包括终止进程 都必须由 接收到信号的进程来执行 而进程要执行信号处理程序 就必须等到它真正运行时 因此 对信号的处理可能需要延迟一段时间

信号没有固有的优先级 如果为一个进程同时产生了两个信号 这两个信号会以任意顺序出现在进程中并会按任意顺序被处理 另外 也没有机制用于区分同一种类的多个信号 如果进程在处理某个信号之前 又有相同的信号发出 则进程只能接收到一个信号 进程无法知道它接收了1个还是42个SIGCONT信号