信号是软件中断,它提供了一种处理异步事件的方法。
有很多条件可以产生信号:
(1)用户按下终端按键,引发终端产生信号。
例如,ctrl+c产生中断信号SIGINT,这是停止一个已经失去控制的程序的方法。
(2)硬件异常产生信号。
例如,除数为0、无效的内存引用。这些异常由硬件检测到,并通知内核。
(3)进程调用kill(2)函数。
将任意信号发送给另一个进程。接收信号进程和发送信号进程的所有者必须相同,或发送信号进程的所有者必须是超级用户。
(4)调用kill(1)命令。
此命令是kill函数的接口。
(5)软件条件产生信号。
例如,SIGURG表示在网络连接上传来带外的数据;SIGPIPE表示在管道的读进程已终止后,一个进程还在写此管道;SIGALRM表示进程所设置的定时器已经超时;SIGABORT表示进程调用abort函数产生夭折信号。
当某个信号出现时,信号的处理有以下三种方式:
(1)忽略此信号。
只有两种信号不能被忽略,SIGKILL和SIGSTOP。不能被忽略的原因:它们向内核和超级用户提供了使进程终止或停止的方法。
(2)捕捉信号。
通知内核在某种信号发生时,调用一个用户函数。
例如,如果捕捉到SIGCHLD信号,则表示一个子进程已经终止,此信号的捕捉函数可以调用waitpid以取得该子进程的进程ID以及它的终止状态;如果进程创建了临时文件,可能要为SIGTERM信号编写一个信号捕捉函数以清除临时文件。
注意:不能捕捉SIGKILL和SIGSTOP信号。
(3)执行系统默认动作。
对大多数信号的系统默认动作是终止该进程。
我们可以通过kill -l命令可以看到系统支持的SIG信号:
下图对SIG信号做了简要概述,在系统默认动作这列,"终止+core"表示进程当前工作目录的core文件中复制了该进程的内存映像。我们可以使用core文件检查进程终止时的状态。
名字 | 说明 | 系统默认动作 |
1 SIGHUP | 连接断开 | 终止 |
2 SIGINT | 终端中断符 | 终止 |
3 SIGQUIT | 终端退出符 | 终止+core |
4 SIGILL | 非法硬件指令 | 终止+core |
5 SIGTRAP | 硬件故障 | 终止+core |
6 SIGABRT | 异常终止(abort) | 终止+core |
7 SIGBUS | 硬件故障 | 终止+core |
8 SIGFPE | 算术异常 | 终止+core |
9 SIGKILL | 终止 | 终止 |
10 SIGUSR1 | 用户定义信号 | 终止 |
11 SIGSEGV | 无效内存引用 | 终止+core |
12 SIGUSR2 | 用户定义信号 | 终止 |
13 SIGPIPE | 写至无读进程的管道 | 终止 |
14 SIGALRM | 定时器超时(alarm) | 终止 |
15 SIGTERM | 终止 | 终止 |
16 SIGSTKFLT | 协处理器栈故障 | 终止 |
17 SIGCHLD | 子进程状态改变 | 忽略 |
18 SIGCONT | 使暂停进程继续 | 继续/忽略 |
19 SIGSTOP | 停止 | 停止进程 |
20 SIGTSTP | 终端停止符 | 停止进程 |
21 SIGTTIN | 后台读控制tty | 停止进程 |
22 SIGTTOU | 后台写控制tty | 停止进程 |
23 SIGURG | 紧急情况(套接字) | 忽略 |
24 SIGXCPU | 超过CPU限制(setrlimit) | 终止或终止+core |
25 SIGXFSG | 超过文件长度限制(setrlimit) | 终止或终止+core |
26 SIGVTALRM | 虚拟时间闹钟(setitimer) | 终止 |
27 SIGPROF | 梗概时间超时(setitimer) | 终止 |
28 SIGWINCH | 终端窗口大小改变 | 忽略 |
29 SIGIO | 异步I/O | 终止/忽略 |
30 SIGPWR | 电源失效/重启动 | 终止/忽略 |
31 SIGSYS | 无效系统调用 | 终止+core |
下面详细说明这些信号:
1 SIGHUP
如果终端检测到一个连接断开,则将此信号送给与该终端相关的控制进程(会话首进程)。
注意,接到此信号的会话首进程可能在后台,这区别于由终端正常产生的几个信号(中断,退出和挂起),这些信号总是传递给前台进程组。
2 SIGINT
当用户按下中断键(ctrl+c),终端驱动程序会产生此信号并发送到前台进程组中的每一个进程。
3 SIGQUIT
当用户按下中断键(ctrl+\),终端驱动程序会产生此信号并发送到前台进程组中的每一个进程。此信号不仅终止前台进程组,同时产生一个core文件。
4 SIGILL
表示进程已经执行一条非法硬件指令。
5 SIGTRAP
表示一个硬件故障。
6 SIGABRT
调用abort时产生此信号。进程异常终止。
7 SIGBUS
表示一个硬件故障。
8 SIGFPE
算数运算异常。
9 SIGKILL
不能被捕获或忽略的信号。杀死任一进程。
10 SIGUSR1
用户定义信号
11 SIGSEGV
表示进程进行了一次无效的内存引用。segmentation violation。
12 SIGUSR2
用户定义信号
13 SIGPIPE
如果在管道的读进程已终止时写管道,则产生此信号。
当类型为SOCK_STREAM的套接字已不再连接时,进程写套接字也产生此信号。
14 SIGALRM
当用alarm函数设置的定时器超时,产生此信号。
当由setitimer(2)函数设置的间隔时间超时时,也产生此信号。
15 SIGTERM
这是由kill(1)命令发送的系统默认终止信号。由于该信号可以被应用程序捕获,使用SIGTERM可以在程序退出之前做好清理工作(相对于SIGKILL来说)。
17 SIGCHLD
在一个进程终止或停止时,SIGCHLD信号被送给其父进程。按系统默认,将忽略此信号。如果父进程希望被告知其子进程的这种状态改变,则应捕捉此信号。
18 SIGCONT
此信号发送给需要继续运行,但当前处于停止状态的进程。如果接收到此信号的进程处于停止状态,则系统默认动作是使该进程继续运行;否则默认动作是忽略此信号。
19 SIGSTOP
此信号停止一个进程。不能被捕获或忽略。
20 SIGTSTP
交互停止信号。当用户在终端上按挂起键(ctrl+z)时,终端驱动程序产生此信号。该信号发送给前台进程组中的所有进程。
21 SIGTTIN
当一个后台进程组进程试图读其控制终端时,终端驱动程序产生此信号。
22 SIGTTOU
当一个后台进程组进程试图写其控制终端时,终端驱动程序产生此信号。
23 SIGURG
此信号通知进程已经发生一个紧急情况。当网络连接上接到带外的数据时,可选择地产生此信号。
24 SIGXCPU
如果进程超过了其软CPU时间限制,则产生此信号。
25 SIGXFSG
如果进程超过了其软文件长度限制,则产生此信号。
26 SIGVTALRM
当由setitimer(2)函数设置的虚拟间隔时间超时时,产生此信号。
28 SIGWINCH
内核维持与每个终端相关联窗口的大小。如果进程通过ioctl设置窗口大小,则内核将SIGWINCH信号发送到前台进程组。
29 SIGIO
表示一个异步I/O事件。
31 SIGSYS
表示一个无效的系统调用。