首页 > 代码库 > sigpending

sigpending

信号的阻塞:通过sigprocmask()将信号集sigset_t中的信号设置为阻塞。SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

一个信号的"生命周期"为:产生(generation)、未决(pending)、递送(delivery)

如果将信号设置为阻塞,那么,在信号产生和递送之间的时间间隔内,称信号是未决的(pending)。 

如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略。

sigpending函数的作用是获取被设置为SIG_BLOCK的信号集。

 

1 static void sig_quit(int signo)
2 {
3     printf("111caught SIGQUIT\n");
4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
5     {
6         printf("can‘t reset SIGQUIT\n");
7     }
8 }

 

 1 int main(int argc, char** argv)
 2 {
 3     sigset_t newmask, oldmask, pendmask;
 4 
 5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
 6     {
 7         printf("can‘t catch SIGQUIT\n");    
 8         return -1;
 9     }
10 
11     //block SIGQUIT and save cureent signal mask
12     sigemptyset(&newmask);
13     sigaddset(&newmask, SIGQUIT);
14 
15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
16     {
17         printf("SIGBLCOK error\n");    
18         return -1;
19     }
20     printf("newmask:%x, oldmask:%x\n", newmask, oldmask);
21 
22     sleep(5);
23     
24     if (sigpending(&pendmask)<0)
25     {
26         printf("sigpending error\n");    
27         return -1;
28     }
29     printf("pendmask:%x\n", pendmask);
30 
31     if (sigismember(&pendmask, SIGQUIT))
32         printf("SIGQUIT pending\n");    
33 
34     if (sigprocmask(SIG_SETMASK, &oldmask, NULL))//解除阻塞
35     {
36         printf("sigprocmask error\n");
37         return -1;
38     }
39     printf("222SIGQUIT unblock\n");
40 
41     sleep(5);
42 
43     return 0;
44 }

运行结果为:

1. 当在第一个sleep 5s期间,Ctrl+\ 产生SIGQUIT信号时:

技术分享

因为在sleep期间产生了SIGQUIT信号,那么此时该信号的状态时pending的,当该信号被设置为不阻塞后,即解除阻塞后,立即捕获该信号。从输出中可以看出,sig_quit中的printf语句先执行,然后再执行sigprocmask之后的printf语句。

2. 如果在第一个sleep 5s期间,不产生SIGQUIT信号,显然,sigpending的输出为0。

技术分享

从结果中可以看到,本次pendmask为0,而上次pendmask为4。

 

 

SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

1 static void sig_quit(int signo)
2 {
3     printf("111caught SIGQUIT\n");
4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
5     {
6         printf("can‘t reset SIGQUIT\n");
7     }
8 }
1 static void sig_quit2(int signo)
2 {
3     printf("xxxcaught SIGQUIT\n");
4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
5     {
6         printf("can‘t reset SIGQUIT\n");
7     }
8 }
 1 int main(int argc, char** argv)
 2 {
 3     sigset_t newmask, oldmask, pendmask;
 4 
 5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
 6     {
 7         printf("can‘t catch SIGQUIT\n");    
 8         return -1;
 9     }
10 
11     //block SIGQUIT and save cureent signal mask
12     sigemptyset(&newmask);
13     sigaddset(&newmask, SIGQUIT);
14 
15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
16     {
17         printf("SIGBLCOK error\n");    
18         return -1;
19     }
20     printf("newmask:%x, oldmask:%x\n", newmask, oldmask);
21 
22     sleep(5);
23     
24     if (signal(SIGQUIT, sig_quit2) == SIG_ERR)
25     {
26         printf("can‘t catch SIGQUIT\n");    
27         return -1;
28     }
29 
30     if (sigpending(&pendmask)<0)
31     {
32         printf("sigpending error\n");    
33         return -1;
34     }
35     printf("pendmask:%x\n", pendmask);
36 
37     if (sigismember(&pendmask, SIGQUIT))
38         printf("SIGQUIT pending\n");    
39 
40     if (sigprocmask(SIG_SETMASK, &oldmask, NULL))
41     {
42         printf("sigprocmask error\n");
43         return -1;
44     }
45     printf("222SIGQUIT unblock\n");
46 
47     sleep(5);
48 
49     return 0;
50 }

运行结果为:

技术分享

在line24中,又重新设置的SIGQUIT的信号处理程序。

 

如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略

 1 int main(int argc, char** argv)
 2 {
 3     sigset_t newmask, oldmask, pendmask;
 4 
 5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
 6     {
 7         printf("can‘t catch SIGQUIT\n");    
 8         return -1;
 9     }
10 
11     //block SIGQUIT and save cureent signal mask
12     sigemptyset(&newmask);
13     sigaddset(&newmask, SIGQUIT);
14 
15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
16     {
17         printf("SIGBLCOK error\n");    
18         return -1;
19     }
20     printf("newmask:%x, oldmask:%x\n", newmask, oldmask);
21 
22     sleep(5);
23     
24     if (sigpending(&pendmask)<0)
25     {
26         printf("sigpending error\n");    
27         return -1;
28     }
29     printf("pendmask:%x\n", pendmask);
30 
31     if (sigismember(&pendmask, SIGQUIT))
32         printf("SIGQUIT pending\n");    
33 
34     if (signal(SIGQUIT, SIG_IGN) == SIG_ERR)
35     {
36         printf("can‘t catch SIGQUIT\n");    
37         return -1;
38     }
39     printf("SIGQUIT IGNORE");
40 
41     sleep(5);
42 
43     return 0;
44 }

运行结果为:

技术分享

 

sigpending