第九章 信号及信号处理
引言:信号是一种软件中断,他提供了一种处理异步事件的方法,也是进程间唯一的异步通信方式,在Linux系统内,根据posix标准扩展以后的信号机制,不仅可以用来通知某进程发生了什么事情,还可以给进程传递数据。
ps:有的知识点嵌入在注释里面
信号:64种,对于信号内核有写好的标准处理函数。
kill -l命令查看所有的信号,现在信号已经增加到65个了,但是在这里我要提一下,从33-64这些信号一般不会采用,这是为了区分可靠信号和不可靠信号而新增加的32个信号
$ 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 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
对于上面部分重要的信号的简单解释
(2) SIGINT ctrl +c 终止信号
(3) ctrl +\ 暂停信号,放入后台
(4) 非法指令
(5) abort 进程异常终止
(7) SIGBUS (虚实关系建立) 总线错误(从写的位置到物理内存,操作系统没有将磁盘的开始位置到物理内存之间建立 联系 mmap(把虚拟内存和磁盘文件的关系映射起来,如果磁盘大小大于0,就建立这种关系
(9) SIGKILL kill - 9 pid 杀死进程
(11) SIGSEGV 段错误
(13) 管道破裂
(14) 闹钟
(15) 缺省终止某个进程,终止掉
(17) 子进程死的时候会给父进程发送这个信号
(19) 进程暂停
(23) SIGURG 紧急数据
(29) 异步IO
可靠信号和不可靠信号
不可靠信号
Linux的信号继承自早期的Unix信号,Unix信号的缺陷
1.信号处理函数执行完毕,信号恢复成默认处理方式(Linux已经改进)
2.会出现信号丢失,信号不排队。
1-31 都是不可靠的,会出现信号丢失现象。
可靠信号
34-64重新设计的一套信号集合
不会出现信号丢失,支持排队,信号处理函数执行完毕,不会恢复成缺省处理方式
实时信号 : 就是可靠信号
非实时信号:不可靠信号
不可靠信号和可靠信号的区别在于前者不支持排队,只递送一次,可能会造成信号丢失,而后者不会。
信号有优先级,信号的优先级比较高,但是在所有信号中,编号越小的先递送,而且如果可靠信号和不可靠信号同时来,大多数情况先递送不可靠信号。
信号捕获处理
进程能够通过系统调用signal告诉内核, 它要如何处理信号, 进程有3个选择。
(1)接收默认处理(通常是消亡)
SIGINT的默认处理是消亡, 进程并不一定要使用signal接收默认处理,但是进程能够通过以下调用来恢复默认处理。
signal(SIGINT, SIG_DFL);
(2)忽略信号
程序可以通过以下调用来告诉内核, 它需要忽略SIGINT。
signal(SIGINT, SIG_IGN);
(3)信号处理函数
作用:程序能够告诉内核,当程序到来时应该调用哪个函数。
主要有两个函数可以实现
1.siganl函数
第二个参数是一个函数指针,传进去一个回调函数。
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void myfunc(int no){
printf("catch you signal:%d\n",no);
}
int main()