信号阻塞
-
信号递达(Delivery):实际执行信号的处理动作。
-
信号未决(pending):信号从产生到递达之间的状态。
-
信号阻塞(block):产生信号,信号也不会被递达。被阻塞的信号产生时将保持在未决状态,信号被阻塞了就不被递达。
未决信号集和阻塞信号集
未决信号集:
信号产生后由于某些原因(主要是阻塞)不能抵达,这类信号的集合称之为未决信号集。在屏蔽解除前,信号一直处于未决状态;若是信号从阻塞信号集中解除阻塞,则该信号会被处理,并从未决信号集中去除。
阻塞信号集:
阻塞信号集中保存的都是被当前进程阻塞的信号。若当前进程收到的是阻塞信号集中的某些信号,这些信号需要暂时被阻塞,不予处理。
二者之间的关系:
阻塞信号集是由程序员自己事先注册信号,然后使用sigprocmask()将需要阻塞的信号加入到阻塞信号集中。程序可以产生注册过的信号,然后这些信号会被阻塞到未决信号集中;程序也可以产生未注册的信号,然后通过未决信号集,触发信号处理函数或默认处理。
未决信号集 是程序产生信号之后,信号保留的地方。当信号到达未决信号集之后,先在阻塞信号集中查看对应的信号是否阻塞(对应的标识位为 1),若阻塞:则保留在未决信号集中–>该信号位对应的标识位 始终为 1;若不阻塞:则处理未决信号集中的信号(信号处理函数或默认处理),然后该标识位由 1---->0,标识 该信号已经被处理(这就是递达状态)
所以即使多次触发存在于阻塞信号集中的 信号,在解除阻塞之后,该信号只会被触发一次。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<fcntl.h>
#include<signal.h>
#include<unistd.h>
void sighandler(int signo){
printf("signo == [%d]\n", signo);
}
int main(){
signal(SIGINT, sighandler);
signal(SIGQUIT, sighandler);
sigset_t set;
sigset_t oldset;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGQUIT);
sigprocmask(SIG_BLOCK, &set, &oldset);
sigset_t pend;
int j = 1;
while(1){
sigemptyset(&pend);
sigpending(&pend);
for(int i =0 ; i < 32; i++){
if(sigismember(&pend, i) == 1