1.信号捕捉过程
1.在执行主控制流程的某条指令时因为中断、异常或系统调用进入内核。
2.内核处理完异常准备回用户模式之前先处理当前进程中可以递送的信号。
3.do_signal(); 如果信号的处理动作为自定义的信号处理函数,则回到用户模式执行信号处理函数(而不是回到主控制流程)
4.void sig_handler(int){ …}; 信号处理函数返回时执行特殊的系统调用sigreturn再次进入内核
5.sys_sigreturn(); 返回用户模式从主控制流程中上次被中断的地方继续向下执行
6.int main(){ …};
上面的流程中第2、3、5步是在内核区实现的,而第1、4、6步是在用户区实现的
注意点:
1.当一个信号被处理的时候,此时又来一个相同的信号,这个信号会被屏蔽,等信号处理完。
2.常规信号集是不支持排队的。未决信号集里边的标记为只能标记为0或者1。之后再来的信号会直接忽略掉。
2.信号的处理函数sigaction
以下为sigaction这个函数实现过程,以SIGALRM信号为例
#include<sys/time.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
void myalarm(int new_value){
printf("过3秒后。每两秒定时一次\n");
printf("------------\n");
};
//过3秒后。每两秒定时一次
int main(){
//sigaction要传入的参数的结构体赋值
struct sigaction act;
act.sa_flags=0;
act.sa_handler=myalarm;
sigemptyset(&act.sa_mask);
sigaction(SIGALRM,&act,NULL);//设置自己的信号捕捉后的操作
//使用setitimer函数产生SIGALARM信号
struct itimerval new_value;
//设置间隔时间值
new_value.it_interval.tv_sec=2;
new_value.it_interval.tv_usec=0;
//设置延迟时间值,3秒之后开始第一次定时
new_value.it_value.tv_sec=3;
new_value.it_value.tv_usec=0;
int ret = setitimer(ITIMER_REAL,&new_value ,NULL);
printf("定时器开始\n");
if(ret == -1){
perror("setitimer");
exit(0);
}
while(1);
return 0;
}
执行效果: