20.1 概述
信号是事件发生时对进程的通知机制(软件中断)。信号中断与硬件中断的相似之处在于打断了程序执行的正常流程,大多数情况下,无法预测信号到达的精确时间
一个具有合适权限的进程能向另一个进程发送信号。信号的这一用法可作为一种同步技术,甚至是进程间通信的原始方式。进程也可以向自身发送信号。然而,发往进程的信号通常都源于内核,引发内核为进程产生信号的各类事件如下:
-
硬件发生异常
硬件检测到错误条件并通知内核,再由内核发送相应信号给相关进程。硬件异常的例子包括执行一条异常的机器语言指令,如被0除,引用了无法访问的内存区域
-
用户键入了能够产生信号的终端特殊字符
如中断字符Control+ C,暂停字符Control+ Z
-
发生了软件事件
如定时器到期。进程执行的CPU时间超限,进程的某个子进程退出等
针对每个信号,都定义了一个唯一的整数,从1开始顺序展开。<signal.h>头文件中以SIGXXX形式的符号对这些整数做了定义。每个信号的实际编号随系统不同而不同。
信号分为两大类:一类是用于内核向进程通知事件,构成标准信号。Linux中标准信号的编号范围为1~31。另一类是实时信号。
信号产生后,稍后会被传递给某一进程,而进程会采取某些措施来响应这些信号。在信号的产生和到达期间,信号处于等待(pending)状态。
通常,一旦内核要调度进程执行,该进程的等待信号会马上送达,如果进程正在执行,则会立即传递信号。然而,有时需要确保一段代码的执行不受传递来的信号中断,为了做到这一点,可以将信号添加到进程的信号掩码中,阻塞指定信号的到达,该信号将保持pending状态,直至稍后对其解除阻塞(从信号掩码中移除)。进程可以使用各种系统调用对其信号掩码添加和移除
信号到达后,进程根据信号可进行如下操作:
- 忽略信号,内核将丢弃信号,信号对进程没有任何影响
- 终止(杀死)进程,进程异常终止,如kill 某个进程
- 产生核心转储文件,同时进程终止
- 暂停进程的执行
- 在暂停进程的执行后,恢复进程的执行
除了根据特定信号而采取默认行为外,程序也能改变信号到达时的响应行为。也将此称之为对信号的处置设置(信号处理函数)。程序可以将对信号的处置设置如下:
-
采取默认行为,适用于撤销之前对信号处理函数的设置,恢复默认方法
-
忽略信号
-
执行信号处理函数,编写的函数,为了响应传递来的信号而执行适当任务。
20.2 信号类型
| 信号名称 | 说明 |
|---|---|
| SIGABRT | 进程调用abort()函数时,系统向进程发送该信号 |
| SIGALRM | 调用alarm()或setitimer()而设置的定时器,到期后,产生该信号 |
| SIGBUS | 发生了某种内存访问错误 |
| SIGCHLD/SIGCLD | 父进程的某一子进程停止/恢复/终止时,向父进程发送该信号 |
| SIGCONT | 恢复已经暂停运行的进程,如果进程正在运行,忽略该信号 |
| SIGEMT | 标识依赖于实现的硬件错误 |
| SIGFPE | 特定类型的算数错误,如除以0 |
| SIGHUP | 当终端断开时,发送该信号给终端控制进程。还可用于守护进程,如init,httpd,守护进程收到该信号时重新进行初始化并重读配置文件 |
| SIGILL | 进程试图执行非法的机器语言指令,系统向进程发送该信号 |
| SIGINFO/SIGPWR | BSD系统中,输入control-T可产生该信号,用户获取前台进程组的状态信息 |
| SIGINT | 用户输入终端终端字符(Control + C)时,终端驱动程序将发送信号给前台进程 |
| SIGIO | 利用fcntl()系统调用时,打开的特定类型的文件描述符(如终端,套接字)发生I/O事件时产生该信号 |
| SIGKILL | 必杀信号,处理程序无法将其阻塞,忽略,捕获,所以总能终止进程 |
| SIGPWR | 电源故障信号 |
| SIGQUIT | 用户在键盘上输入退出字符(Control + \)时,内核将信号发往前台进程组,默认情况下,信号终止进程,并生成可用于调试的核心转储文件。进程如果陷入无限循环或无影响时,使用该信号就很合适。 |
| SIGSEGV | 当应用进程对内存的引用无效时,就会产生该信号。如引用的页不存在,进程更新只读内存,在用户态访问内核的不分内存等 |
| SIGSTOP | 停止进程 |
| SIGSYS | 进程发起的系统调用有误 |
| SIGTERM | 用来终止进程的标准信号,也是kill,killall命令所使用的默认信号。精心设计的程序应当为该信号设置处理器程序,以便于能预先清除临时文件和释放资源**** |
| SIGTSTP | 作业控制的停止信号,当用户在键盘上输入挂起字符(Control +Z)时,将引发该信号给前台进程组,使其停止运行 |
| SIGTTIN | 作业控制shell运行时,若后台进程组试图对终端进行read()操作,终端驱动程序则向该进程组发送此信号。该信号默认将停止进程 |
| SIGTTOU | 后台作业的终端输出 |
| SIGXCPU | 当进程的CPU时间超出对应的资源限制时,发送此信号给进程 |

最低0.47元/天 解锁文章
2301

被折叠的 条评论
为什么被折叠?



