Linux中的信号
信号是进程在运行过程中,由自身产生或由进程外部发过来的消息(事件)。每个信号用一个整型常量宏表示,以SIG开头,比如SIGCHLD、SIGINT等,它们在系统头文件中定义,也可以通过在shell下键入kill –l查看信号列表,或者键入man 7 signal查看更详细的说明。
|
|
---|---|
kill -l |
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX |
信号是由内核生成,让内核生成信号的请求来自3个地方:
- 用户:用户能够通过输入CTRL+c、Ctrl+,或者是终端驱动程序分配给信号控制字符的其他任何键来请求内核产生信号;
- 内核:当进程执行出错时,内核会给进程发送一个信号,例如非法段存取(内存访问违规)、浮点数溢出等;
- 进程:一个进程可以通过系统调用kill给另一个进程发送信号,一个进程可以通过信号和另外一个进程进行通信。
由进程的某个操作产生的信号称为同步信号(synchronous signals),例如除0;由像用户击键这样的进程外部事件产生的信号叫做异步信号。(asynchronous signals)。
进程接收到信号以后,可以有如下3种选择进行处理:
- 接收默认处理:接收默认处理的进程通常会导致进程本身消亡。例如连接到终端的进程,用户按下CTRL+c,将导致内核向进程发送一个SIGINT的信号,进程如果不对该信号做特殊的处理,系统将采用默认的方式处理该信号,即终止进程的执行;
- 忽略信号:进程可以通过代码,显示地忽略某个信号的处理,例如:signal(SIGINT,SIGDEF);但是某些信号是不能被忽略的,
- 捕捉信号并处理:进程可以事先注册信号处理函数,当接收到信号时,由信号处理函数自动捕捉并且处理信号。
有两个信号既不能被忽略也不能被捕捉,它们是SIGKILL和SIGSTOP。即进程接收到这两个信号后,只能接受系统的默认处理,即终止线程。
当一个进程执行信号处理时,如果还有其他信号到达,那么新的信号会被阻断直到处理器返冋为止。
在程序执行时,出现了一个错误或任何异常,内核就可以使用信号来通知相应的进程。
|
|
---|---|
信号 |
用于通信、同步进程和简化进程间通信、处理异常和中断 当一个事件发生时,会产生一个信号,然后内核会将事件传递到接收的进程。 |
运行在用户模式下的进程接收到信号后会进行相应的处理 | |
运行在内核模式下的进程接收到信号时,会等到该进程返回到用户模式时才会开始 | |
发送到非运行进程的信号一定是由内核保存,直到进程重新执行为止 | |
休眠的进程可以是可中断的,也可以是不可中断的。 如果一个在可中断休眠状态的进程(例如,等待终端输入的进程)收到了一个信号,那么内核会唤醒这个进程来处理信号。 如果一个在不可中断休眠状态的进程收到了一个信号,那么内核会拖延此信号,直到该事件完成为止 |
信号的名称和值
下标所列出的信号是 POSIX 标准的一部分,它们通常被缩写成不带SIG
前缀,例如,SIGHUP 通常被简单地称为 HUP。
信 号
|
默认行为
|
描 述
|
信号值
|
---|---|---|---|
信 号
|
默认行为
|
描 述
|
信号值
|
SIGABRT | 生成 core 文件然后终止进程 | 这个信号告诉进程终止操作。ABRT 通常由进程本身发送,即当进程调用 abort() 函数发出一个非正常终止信号时 | 6 |
SIGALRM | 终止 | 警告时钟 | 14 |
SIGBUS | 生成 core 文件然后终止进程 | 当进程引起一个总线错误时,BUS 信号将被发送到进程。例如,访问了一部分未定义的内存对象 | 10 |
SIGCHLD | 忽略 | 当了进程结束、被中断或是在被中断之后重新恢复时,CHLD 信号会被发送到进程 | 20 |
SIGCONT | 继续进程 | CONT 信号指不操作系统重新开始先前被 STOP 或 TSTP 暂停的进程 | 19 |
SIGFPE | 生成 core 文件然后终止进程 | 当一个进程执行一个错误的算术运算时,FPE 信号会被发送到进程 | 8 |
SIGHUP | 终止 | 当进程的控制终端关闭时,HUP 信号会被发送到进程 | 1 |
SIGILL | 生成 core 文件然后终止进程 | 当一个进程尝试执行一个非法指令时,ILL 信号会被发送到进程 | 4 |
SIGINT | 终止 | 当用户想要中断进程时,INT 信号被进程的控制终端发送到进程 | 2 |
SIGKILL | 终止 | 发送到进程的 KILL 信号会使进程立即终止。KILL 信号不能被捕获或忽略 | 9 |
SIGPIPE | 终止 | 当一个进程尝试向一个没有连接到其他目标的管道写入时,PIPE 信号会被发送到进程 | 13 |
SIGQUIT | 终止 | 当用户要求进程执行 core dump 时,QUIT 信号由进程的控制终端发送到进程 | 3 |
SIGSEGV | 生成 core 文件然后终止进程 | 当进程生成了一个无效的内存引用时,SEGV 信号会被发送到进程 | 11 |
SIGSTOP | 停止进程 | STOP 信号指示操作系统停止进程的执行 | 17 |
SIGTERM | 终止 | 发送到进程的 TERM 信号用于要求进程终止 | 15 |
SIGTSTP | 停止进程 | TSTP 信号由进程的控制终端发送到进程来要求它立即终止 | 18 |
SIGTTIN | 停止进程 | 后台进程尝试读取时,TTIN 信号会被发送到进程 | 21 |
SIGTTOU | 停止进程 | 后台进程尝试输出时,TTOU 信号会被发送到进程 | 22 |
SIGUSR1 | 终止 | 发送到进程的 USR1 信号用于指示用户定义的条件 | 30 |
SIGUSR2 | 终止 | 同上 | 31 |
SIGPOLL | 终止 | 当一个异步输入/输出时间事件发生时,POLL 信号会被发送到进程 | 23 |
SIGPROF | 终止 | 当仿形计时器过期时,PROF 信号会被发送到进程 | 27 |
SIGSYS | 生成 core 文件然后终止进程 | 发生有错的系统调用时,SYS 信号会被发送到进程 | 12 |
SIGTRAP | 生成 core 文件然后终止进程 | 追踪捕获/断点捕获时,会产生 TRAP 信号。 | 5 |
SIGURG | 忽略 | 当侖一个 socket 有紧急的或是带外数据可被读取时,URG 信号会被发送到进程 | 16 |
SIGVTALRM | 终止 | 当进程使用的虚拟计时器过期时,VTALRM 信号会被发送到进程 | 26 |
SIGXCPU | 终止 | 当进程使用的 CPU 时间超出限制时,XCPU 信号会被发送到进程 | 24 |
SIGXFSZ | 生成 core 文件然后终止进程 | 当文件大小超过限制时,会产生 XFSZ 信号 | 25 |