先介绍有关信号的三个概念:
- 信号未决(pending):信号从产生到递达之间的状态。
- 信号递达(delivery):实际执行信号的处理动作。
- 信号阻塞(block):进程可以选择阻塞某个信号。被阻塞的信号将保持在未决状态,知道解除阻塞,才执行递达的动作。
注意:信号阻塞和忽略信号的区别:
只要信号被阻塞就不会被递达。而忽略信号时在递达之后的一种处理动作。
信号在内核中的表示示意图如下:
block:阻塞集信号。用位图表示,只需4字节。位图的下标表示信号的编号,内容为1,表示该信号阻塞,为0,表示该信号非阻塞。
pending:未决信号集。用位图表示,只需4字节。位图的下标表示信号的编号,内容为1,表示收到该信号,为0,表示未收到该信号。
handler:递达。设置对应信号的处理方式,SIG_DFL:表示默认。SIG_IGN:表示忽略。还可选择相应的处理函数指针。
例如说图中的2号信号。收到了2号信号,但是2号信被阻塞,不能递达。该信号递达为忽略。
未决和阻塞标志可以⽤用相同的数据类型sigset_t来存储,sigset_t称为信号集。
阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask), 这里的“屏蔽”应该理解为阻塞⽽而不是忽略。
下面介绍信号集的操作函数:
int sigemptyset(sigset_t *set); //将信号集清零
int sigfillset(sigset_t *set); //将信号集置位
int sigaddset(sigset_t *set, int signo);// 添加某种有效信号
int sigdelset(sigset_t *set, int signo); //删除某种有效信号
int sigismember(const sigset_t *set, int signo); //判断某种信号是否在该信号集里
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); //读取或更改信号的屏蔽字(阻塞信号集)
如果oset是⾮非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是⾮非空指 针,则 更改进程的信号屏蔽字,参数how指⽰示如何更改。如果oset和set都是⾮非空指针,则先 将原来的信号 屏蔽字备份到oset⾥里,然后根据set和how参数更改信号屏蔽字。假设当前的 信号屏蔽字为mask,下表说明了how参数的可选值。
how可选值如下&#x