Linux环境编程--信号的捕捉和使用
信号:
信号是软件中断,它提供了一种处理异步事件的方法。每个信号都有一个名字,这些名字都是以SIG开头。
在Linux环境下查看各个信号的命令:
kill -l:
在头文件<signal.h>中,信号名都被定义为正整数常量即信号编号。
在某个信号发生时,可以告诉内核按照下面三种方式进行处理:
(1)忽略此信号 (2)捕捉此信号 (3)执行系统默认动作。
对以上特殊信号进行说明:
1.编号为0的信号有特殊用途,我们可以给某个进程发0号信号来判断该进程是否正在运行。
2.kill命令默认发SIGTERM信号。
如果SIGTERM被捕捉后,那么kill命令就不能停止该进程运行,这时需要使用kill -9(SIGKILL)可以强制杀死某个进程。
常用信号:SIGINT,SIGKILL(不可被捕捉),SIGPIPE,SIGSEGV,SIGTERM,SIGUSR1,SIGUSR2;
不可捕捉:只执行系统默认操作。
3.在Centos6的Linux环境下:在命令行输入ctrl + C 会产生SIGINT信号。在程序运行时出现Segmentation fault,程序会发送SIGSEGV信号给系统来终止程序。
4.由于信号是突发的,所以当系统收到信号后,会立即停下当前执行程序,去执行接到信号后的程序,完成接到信号后的程序之后,处理刚刚停下的程序。
捕捉信号:
为了做到这点,要通知内核再某种信号发生时,调用一个用户函数。在用户函数中,可执行用户希望对这种事件进行处理。
函数signal(int signum,sighandler_t handler):可以用来捕捉信号。第一个表示信号对应的信号编号,第二个是捕捉信号后实现的函数。
一个简单的捕捉信号程序:
捕捉SIGINT、SIGTERM、SIGALRM信号,并打印出捕捉的信息
程序结果:
注:
其中SIGINT、SIGTERM信号需要分别使用Linux命令ctrl + c 以及killall test来产生。
我们可以通过Linux命令的ps aux来查看当前系统所有正在运行的进程。
最后调用killall -9 test来杀死该进程。可见,killall -9确实不可被捕捉。