信号捕捉特性:
1.进程正常运行时,默认PCB中有一个信号屏蔽字,假定为a,他决定了进程自动屏蔽哪些信号。当注册了某个信号捕捉函数,捕捉到该信号以后,要调用该函数。而该函数有可能执行很长时间,在这期间所屏蔽的信号不由a来指定。而用sa_mask来指定。调用完信号处理函数,再恢复为a。
2.XXX信号捕捉函数执行期间,XXX信号自动被屏蔽。
3.阻塞的常规信号不支持排队,产生多次只记录一次。(后32个实时信号支持排队)
4.在sa_mask覆盖阻塞信号集期间,若递送的信号位为阻塞,则不执行捕捉函数,相应的未决信号集该位被设为1(信号只有在非阻塞下才能被捕捉)
1 /*
2 sigaction()头文件 #include<signal.h>
3 原型: int sigaction(int signum,const struct sigaction *act,struct sigaction * oldact);
4 signum: 待捕捉的信号
5 act: 处理动作,传入参数
6 oldact: 旧处理动作,传出参数
7 struct sigaction{
8 void (*sa_handler)(int); 指定要执行的动作
9 void (*sa_sigaction)(int,siginfo_t *,void *);
10 sigset_t sa_mask; 用于指定在信号捕捉函数执行期间所屏蔽的信号集
11 int sa_flags; 通常设置为0,表示使用默认属性
12 默认属性(屏蔽重复信号,即使没有设置sa_mask)
13 void (*sa_restorer)(void); 废弃(不用了)
14 };
15 返回值:成功返回0;失败返回-1,设置errno
16 作用:注册信号捕捉函数(与signal类似)
17 */
18 #include<stdio.h>
19 #include<unistd.h>
20 #include<signal.h>
21 #include<stdlib.h>
22 void my_action(int)
23 {
24 printf("\n-------\n");
25 }
26 void main(void)
27 {
28 int ret;
29 struct sigaction act,oldact;
30 //设置处理动作
31 act.sa_flags=0;
32 // sigemptyset(&act->sa_mask);
33 act.sa_handler=my_action;
34 ret=sigaction(SIGINT,&act,&oldact);
35 if(ret==-1){
36 perror("sigaction error\n");
37 }
38 while(1);
39 }
18 #include<stdio.h>
19 #include<unistd.h>
20 #include<signal.h>
21 #include<stdlib.h>
22 void my_action(int)
23 {
24 printf("\n-------\n");
25 sleep(1);
26 printf("finish\n");
27 }
28 void print(sigset_t *ped)
29 {
30 int i;
31 for(i=1;i<32;i++){
32 if(sigismember(ped,i)==1){//判断某个信号是否在信号集中
33 putchar('1');//打印int类型变量
34 }else
35 printf("0");
36 }
37 printf("\n");
38 }
39 void main(void)
40 { //在sa_mask集中将SIGINT设为1
41 int ret;
42 sigset_t ped;
43 struct sigaction act,oldact;
44 act.sa_flags=0;
45 sigemptyset(&act.sa_mask);
46 sigaddset(&act.sa_mask,SIGINT);
47 sigprocmask(SIG_BLOCK,&act.sa_mask,NULL);
48 act.sa_handler=my_action;
49 ret=sigaction(SIGINT,&act,&oldact);
50 if(ret==-1){
51 perror("sigaction error\n");
52 }
53 while(1){
54 sleep(1);
55 sigpending(&ped);
56 print(&ped);
57 }
58 }