信号的基本概念
Linux中信号有64个,常见信号有31个,用kill -l即可查看:
每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中定义#define SIGINT 2。
所以,使用kill命令时既可以 kill -SIGINT 9527 也可以是 kill -2 9527 其中9527为进程ID。
信号处理的常见方式
1.忽略此信号
2.执行该信号的默认处理过程
3.提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式成为捕捉(Catch)一个信号
产生信号方式
1.通过终端按键产生信号,例如ctrl+c
2.调用系统函数向进程发信号,例如kill -9 9527
3.由软件条件产生信号,例如alarm函数
#include<unistd.h>
unsigned int alarm(unsigned int seconds);
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发送SIGALRM信号,该信号的默认处理动作是终止当前进程。
#include<stdio.h>
#include<unistd.h>
int main()
{
int count = 0;
alarm(1);
while(1)
{
printf("%d\n",count++);
}
return 0;
}
可见这个程序在1秒之内不停地数秒,1秒钟到了就被SIGALRM信号终止。
信号其他相关概念
信号递达:实际执行信号的处理动作称为信号递达(Delivery)
信号未决:信号从产生到递达之间的状态,称为信号未决(Pending)
阻塞(Block):进程可以选择阻塞(Block)某个信号
被阻塞的信号产生时保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作
注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作
捕捉信号
当进程从内核态返回用户态时,要对信号进行检测
信号的捕捉过程