Sigpending, sigaction
Signal blocking: Use sigprocmask () to set the signal in the signal set sigset_t to blocking. SIG_BLOCK refers to the "Delivery blocking" of the corresponding signal. When the kernel delivers a previously blocked signal to the process (rather than when the signal is generated ), then the process can change the action on the signal before the signal is delivered to it.
The "Life Cycle" of a signal is: generation, pending, and delivery)
If the signal is set to blocking, the signal is called pending during the interval between signal generation and delivery ).
If the signal is set to be blocked and the signal action is the default action of the system or capture the signal, when the signal is generated, the process will keep the status of the signal to pending (pending) status until the signal is blocked or the action of the signal is ignored.
The sigpending function is used to obtain the Signal Set set to 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 (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 mask12 sigemptyset (& newmask ); 13 sigaddset (& newmask, SIGQUIT); 14 15 if (sigprocmask (SIG_BLOCK, & newmask, & oldmask) <0) // blocked SIGQUIT signal 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 )) // unblock 35 {36 printf ("sigprocmask error \ n"); 37 return-1; 38} 39 printf ("222 SIGQUIT unblock \ n "); 40 41 sleep (5); 42 43 return 0; 44}
The running result is:
1. When Ctrl + \ generates the SIGQUIT signal during the first sleep 5s:
Because a SIGQUIT signal is generated during sleep, the signal status is pending. When the signal is set to not blocked, that is, the signal is immediately captured after the blocking is removed. From the output, we can see that the printf statement in sig_quit is executed first, and then the printf statement after sigprocmask is executed.
2. If no SIGQUIT signal is generated during the first sleep 5s, the output of sigpending is obviously 0.
The result shows that the pendmask is 0, and the last pendmask is 4.
SIG_BLOCK refers to the "Delivery blocking" of the corresponding signal. When the kernel delivers a previously blocked signal to the process (rather than when the signal is generated ), then the process can change the action on the signal before the signal is delivered to it.
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 (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 mask12 sigemptyset (& newmask ); 13 sigaddset (& newmask, SIGQUIT); 14 15 if (sigprocmask (SIG_BLOCK, & newmask, & oldmask) <0) // blocked SIGQUIT signal 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 ("222 SIGQUIT unblock \ n"); 46 47 sleep (5 ); 48 49 return 0; 50}
The running result is:
In line24, The SIGQUIT signal processing program is reset.
If the signal is set to be blocked and the signal action is the default action of the system or capture the signal, when the signal is generated, the process will keep the status of the signal to pending (pending) status until the signal is blocked orChange the signal action to ignore.
1 int main (int argc, char ** argv) 2 {3 sigset_t newmask, oldmask, pendmask; 4 5 if (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 mask12 sigemptyset (& newmask ); 13 sigaddset (& newmask, SIGQUIT); 14 15 if (sigprocmask (SIG_BLOCK, & newmask, & oldmask) <0) // blocked SIGQUIT signal 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}
The running result is: