信号基本概念
1、中断 :中断源--》中断屏蔽?--》保护现场--》中断处理--》恢复现场。
中断个数固定。中断向量:保存固定个数中断处理程序入口地址
硬件中断(外部中断):外设
软件中断(内部中断):程序出错或程序调用指令
2、信号:异步事件响应,有某些错误条件发生,是在软件层次上对中断的模拟。
信号、中断相似点:
相同的异步通信方式
检测到信号或者中断时,都暂停正在执行的程序,而转去执行相应处理程序
都在处理完毕后返回原断点
对信号和中断都可进行屏蔽
区别:
中断有优先级,信号没有优先级,所有信号平等
信号处理程序在用户态运行,中断处理程序内核态运行
中断响应是及时的,而信号响应有较大延迟
kill -l :查看UNIX支持的64个信号
例如几个常见的:
man 7 signal 中断默认处理程序。
进程对信号的三种响应:
1、忽略信号(SIGKILL【杀死进程信号,不能忽略也不能捕获】和SIGSTOP【停止进程】不能忽略);
2、捕获并处理信号
3、执行默认操作。
下面介绍一个signal函数,并看几个例子:
#include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdlib.h> #include<stdio.h> #include<errno.h> #include<string.h> #include<signal.h> #define ERR_EXIT(m)\ do\ {\ perror(m);\ exit(EXIT_FAILURE);\ }while(0) //宏要求一条语句 void handler(int sig); int main(int argc,char*argv[]) { signal(SIGINT,handler);//ctrl+c 安装信号。_sighandler_t signal(int signum,_sighandler_t handler)。第二个参数为SIG_ING则屏蔽该信号。若为SIG_DFL则恢复默认行为。 for(;;) { pause();//进程挂起,直到有一个信号来临,处理程序返回pause被唤醒。 printf("pause return \n"); } //ctrl+\退出。 signal(SIGINT,hanler) 返回SIGINT默认处理程序 signal(SIGINT,handler2) 返回handler return 0; } void handler(int sig)//sig是signum。信号处理程序 { printf("recv a sig=%d\n",sig); sleep(1); }
另一个例子
1 #include<unistd.h> 2 #include<sys/types.h> 3 #include<sys/stat.h> 4 #include<fcntl.h> 5 #include<stdlib.h> 6 #include<stdio.h> 7 #include<errno.h> 8 #include<string.h> 9 10 #include<signal.h> 11 #define ERR_EXIT(m)\ 12 do\ 13 {\ 14 perror(m);\ 15 exit(EXIT_FAILURE);\ 16 }while(0) //宏要求一条语句 17 void handler(int sig); 18 int main(int argc,char*argv[]) 19 { 20 21 __sighandler_t oldhandler;//双下划线 22 oldhandler=signal(SIGINT,handler); //ctrl+\退出。 signal(SIGINT,hanler) 返回SIGINT的默认处理程序 signal(SIGINT,handler2) 返回handler 23 if(oldhandler==SIG_ERR) 24 ERR_EXIT("signal error"); 25 while(getchar()!='\n') 26 ; 27 /*if((signal(SIGINT,oldhandler))==SIG_ERR) 28 ERR_EXIT("signal error");//SIGINT默认处理程序是退出 29 */ //等价于 30 if((signal(SIGINT,SIG_DFL))==SIG_ERR) 31 ERR_EXIT("signal error"); 32 for(;;); 33 return 0; 34 35 36 } 37 void handler(int sig)//sig是signum 38 { 39 printf("recv a sig=%d\n",sig); 40 41 }