Linux系统调用之sigprocmask、sigpending函数(设置内核阻塞信号集,查看内核未决信号集)

前言

如果,想要深入的学习标准C库中的sigprocmask、sigpending函数,还是需要去自己阅读Linux系统中的帮助文档。

具体输入命令:

man 3 sigprocmask/sigpending

即可查阅到完整的资料信息。

sigprocmask 函数

sigprocmask()函数是Linux中的一个系统调用,用于将自定义信号集中的数据设置到内核中(设置阻塞,解除阻塞,替换),即决定哪些信号可以被进程接收和处理。它允许进程更改当前的内核的阻塞信号集以阻止(屏蔽)或允许(取消屏蔽)特定的信号传递到进程。

sigprocmask()函数的原型如下:

#include <signal.h> // 使用此函数需导入这个头文件

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数说明:

  • how:决定如何修改内核阻塞信号集,有以下几种方式:
    • SIG_BLOCK:将内核阻塞信号集与给定的自定义信号集合set进行逻辑或操作,即将set中的信号添加到屏蔽字中。
    • SIG_UNBLOCK:将内核阻塞信号集与给定的自定义信号集合set的补集进行逻辑与操作,即从屏蔽字中移除set中的信号。
    • SIG_SETMASK:将内核的阻塞信号集设置为给定的信号集合set。
  • set:指向一个信号集合的指针,表示需要修改的信号集合。
  • oldset:指向一个信号集合的指针,用于存储修改前的内核的阻塞信号集。如果不关心旧的内核的阻塞信号集,可以传递NULL。

返回值:

  • 成功时,返回0。
  • 出错时,返回-1,并设置errno。

在调用sigprocmask()之后,内核的阻塞信号集将根据how参数的值进行相应的修改。被屏蔽的信号不会被进程接收,而会被暂时挂起。当信号再次变得可接收时,这些信号将被传递给进程。

sigpending 函数

sigpending()函数是Linux中的一个系统调用,用于查询当前进程的未决信号集合。未决信号集合是指那些已经发送给进程但尚未被处理的信号。这些信号可能因为被屏蔽而无法立即传递给进程。

sigpending()函数的原型如下:

#include <signal.h> // 使用此函数需导入这个头文件

int sigpending(sigset_t *set);

参数说明:

  • set:指向一个信号集合的指针,用于存储当前进程的未决信号集合。

返回值:

  • 成功时,返回0。
  • 出错时,返回-1,并设置errno。

当调用sigpending()函数时,它将把当前进程的未决信号集合复制到set指针所指向的信号集合中。可以使用如sigismember()等函数检查特定信号是否存在于未决信号集合中。

以下是一个sigprocmask()、sigpending()函数的使用示例:

#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    sigset_t set;
    if (sigemptyset(&set) == -1)
    {
        perror("sigemptyset");
        exit(0);
    }
    if (sigaddset(&set, SIGINT) == -1)
    {
        perror("sigaddset");
        exit(0);
    }
    if (sigaddset(&set, SIGQUIT) == -1)
    {
        perror("sigaddset");
        exit(0);
    }
    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
    {
        perror("sigprocmask");
        exit(0);
    }

    int num = 0;
    while (1)
    {
        sigset_t ret;
        if (sigpending(&ret) == -1)
        {
            perror("sigpending");
            exit(0);
        }

        for (int i = 1; i < 32; ++i)
        {
            if (sigismember(&ret, i) == 1)
            {
                printf("1");
            }
            else if (sigismember(&ret, i) == 0)
            {
                printf("0");
            }
            else
            {
                perror("sigismember");
                exit(0);
            }
        }
        printf("\n");

        ++num;
        if (num == 10)
        {
            if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
            {
                perror("sigprocmask");
                exit(0);
            }
        }
        sleep(1);
    }
    return 0;

}

这个程序会把所有的常规信号(1-31)的未决状态循环打印到屏幕,每隔一秒打印一次

总结

这篇文章介绍了标准C库中的sigprocmask、sigpending这两个函数。如果大家想要了解更多的标准C库函数知识,Linux系统调用函数知识,大家请看这两篇文章:

最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿宋同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值