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

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

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

![img](https://mmbiz.qpic.cn/mmbiz_jpg/YeUmRxGrEBYHf37nN817iaLmRaRLxxEsvttibax9wT0ySLX4ZR2FicHu3Ipia6OHNWI1rGwd2WCr62RlwDiaTJX5wRQ/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=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}

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值