17

Linux系统编程—信号集操作函数

 3 years ago
source link: http://www.cnblogs.com/yychuyu/p/13776831.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

先来回顾一下 未决信号集 是怎么回事。

信号从产生到抵达目的地,叫作 信号递达 。而信号从产生到递达的中间状态,叫作信号的 未决状态 。产生未决状态的原因有可能是信号受到阻塞了,也就是 信号屏蔽字 (或称阻塞信号集,mask)对应位被置1。阻塞信号集和未决信号集均是由内核维护的,整个过程如下图示:

QZbQJrv.jpg!mobile

我们有时需要屏蔽某个信号,就需要去修改阻塞信号集。那么,我们该如何修改阻塞信号集?系统提供的一个方法是,我们 先创建一个跟阻塞信号集一样的集合,再利用它去修改阻塞信号集。

系统提供了一系列的 信号集设定函数 。这些函数如下所示:

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

q2Ijume.jpg!mobile

有收获?希望老铁们来个三连击,给更多的人看到这篇文章


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK