先来回顾一下 未决信号集 是怎么回事。
信号从产生到到达目的地,叫作 信号递达 。而信号从产生到递达的中间状态,叫作信号的 未决状态 。产生未决状态的起因有可能是信号受到阻塞了,也就是 信号屏蔽字(或称阻塞信号集,mask)对应位被置 1。阻塞信号集和未决信号集均是由内核保护的,整个过程如下图示:
咱们有时须要屏蔽某个信号,就须要去批改阻塞信号集。那么,咱们该如何批改阻塞信号集?零碎提供的一个办法是,咱们 先创立一个跟阻塞信号集一样的汇合,再利用它去批改阻塞信号集。
零碎提供了一系列的 信号集设定函数。这些函数如下所示:
sigset_t set;
信号集数据类型,实质是 typedef unsigned long sigset_t;
int sigemptyset(sigset_t *set);
将某个信号集清 0
int sigfillset(sigset_t *set);
将某个信号集置 1
int sigaddset(sigset_t *set, int signum);
将某个信号退出信号集
int sigdelset(sigset_t *set, int signum);
将某个信号清出信号集
以上几个函数返回值均是:胜利:0;失败:-1
int sigismember(const sigset_t *set, int signum);
判断某个信号是否在信号集中
返回值:在汇合:1;不在:0;出错:-1
应用以上这些函数创立完信号集后,要如何去扭转阻塞信号集呢?零碎又提供了一个函数:sigprocmask 函数。
sigprocmask 函数能够用来 屏蔽信号 ,也能够用来 解除屏蔽信号,其本质就是利用咱们创立的信号集去扭转阻塞信号集。
函数原型:
int sigprocmask(int how, const sigset_t set, sigset_t oldset);
返回值:
胜利:0;失败:-1,设置 errno
参数解释:
set:传入参数,是一个位图,set 中哪地位 1,就示意以后过程屏蔽哪个信号。
oldset:传出参数,保留旧的信号屏蔽集。这个与 setitimer 有点类似。
how参数取值:
假如以后的信号屏蔽字为 mask
1.SIG_BLOCK:当 how 设置为此值,set 示意须要屏蔽的信号。相当于 mask = mask | set
2.SIG_UNBLOCK:当 how 设置为此,set 示意须要解除屏蔽的信号。相当于 mask = mask & ~set
3.SIG_SETMASK:当 how 设置为此,set 示意用于代替原始屏蔽及的新屏蔽集。相当于 mask = set 若,调用 sigprocmask 解除了对以后若干个信号的阻塞,则在 sigprocmask 返回前,至多将其中一个信号递达。
咱们如何读取未决信号集?零碎提供了sigpending 函数。
函数原型:
int sigpending(sigset_t *set);
参数阐明:
set 传出参数。
返回值:
返回值:胜利:0;失败:-1,设置 errno
例:把所有惯例信号的未决状态打印至屏幕。
1#include
2#include
3#include
4
5void printPending(sigset_t *set)
6{
7 int i = 0;
8
9 for (i = 0; i < 32; i++) {10 if (sigismember(set, i) == 1)
11 printf("1");
12 else
13 printf("0");
14 }
15 printf("\n");
16}
17
18int main()
19{
20 sigset_t set, oldset, pendset;
21 sigemptyset(&set);
22 sigaddset(&set, SIGQUIT); // ctrl + \ 将产生 SIGQUIT 信号
23 sigprocmask(SIG_BLOCK, &set, &oldset);
24 while (1) {25 sigpending(&pendset);
26 printPending(&pendset); // 写一个函数打印未决信号集
27 sleep(1);
28 }
29}
最初,最近很多小伙伴找我要Linux 学习路线图,于是我依据本人的教训,利用业余时间熬夜肝了一个月,整顿了一份电子书。无论你是面试还是自我晋升,置信都会对你有帮忙!
收费送给大家,只求大家金指给我点个赞!
电子书 | Linux 开发学习路线图
也心愿有小伙伴能退出我,把这份电子书做得更完满!
有播种?心愿老铁们来个三连击,给更多的人看到这篇文章
举荐浏览:
- 干货 | 程序员进阶架构师必备资源免费送
- 神器 | 反对搜寻的资源网站