下面是信号集操作函数的原型:
#include <signal.h>int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set, int signum);int sigdelset(sigset_t *set, int signum);int sigismember(const sigset_t *set, int signum);
- sigemptyset: 初始化set指向的信号集,将所有比特位置0
- sigfillset: 初始化set指向的信号集,将所有比特位置1
- sigaddset: 把set指向的信号集中signum信号对应的比特位置1
- sigdelset: 把set指向的信号集中signum信号对应的比特位置0
- sigismember: 判断signum信号是否存在set指向的信号集中(本质是信号判断对应位是否为1)
阻塞信号集操作函数——sigprocmask:
#include<signal.h>int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);功能:检查或修改信号阻塞集 , 根据how指定的方法对进程的阻塞集合进行修改,新的信号阻塞集由set指定,而原先的信号阻塞集合由oldset保存 。参数:how:信号阻塞集合的修改方法,有3种情况:SIG_BLOCK:向信号阻塞集合中添加set信号集 , 新的信号掩码是set和旧信号掩码的并集 。相当于mask=mask丨set 。SIG_UNBLOCK:从信号阻塞集合中删除set信号集,从当前信号掩码中去除set中的信号 。相当于mask=mask&~set 。SIG_SETMASK:将信号阻塞集合设为set信号集,相当于原来信号阻塞集的内容清空 , 然后按照set中的信号重新设置信号阻塞集 。相当于mask=set 。set:要操作的信号集地址 。若set为NULL,则不改变信号阻塞集合 , 函数只把当前信号阻塞集合保存到oldset中 。oldset: 保存原先信号阻塞集地址 。返回值:成功:0失败:-1
未决信号集操作函数——sigpending:#include<signal.h>int sigpending(sigset_t *set);功能:读取当前进程的未决信号集参数:set:未决信号集返回值:成功:0失败:-1
代码示例:实验一:把进程中信号屏蔽字2号信号进行阻塞,然后每隔1s对未决信号集进行打印,观察现象 。
#include <stdio.h>#include <unistd.h>#include <signal.h>void PrintPending(sigset_t* pend){int i = 0;for (i = 1; i < 32; ++i){if (sigismember(pend, i)){printf("1");}else{printf("0");}}printf("\n");}int main(){sigset_t set, oset;sigset_t pending;// 使用系统函数对信号集进行初始化sigemptyset(&set);sigemptyset(&oset);sigemptyset(&pending);// 阻塞2号信号// 先用系统函数对set信号集进行设置sigaddset(&set, 2);// 使用sigprocmask函数更改进程的信号屏蔽字// 第一个参数,三个选项:SIG_BLOCK(mask |= set) SIG_UNBLOCK(mask &= ~set) SIG_SETMASK(mask = set)sigprocmask(SIG_BLOCK, &set, &oset);int flag = 1; // 表示已经阻塞2号信号int count = 0;while (1){// 使用sigpending函数获取pending信号集sigpending(&pending);// 打印pending位图PrintPending(&pending);sleep(1);}return 0;}
运行结果如下:可以看到,进程收到2号信号时,且该信号被阻塞 , 处于未决状态,未决信号集中2号信号对应的比特位由0置1

文章插图
实例2: 将上面的代码进行修改,进行运行10s后,我们将信号屏蔽字中2号信号解除屏蔽
【二 Linux进程间通信】
#include <stdio.h>#include <unistd.h>#include <signal.h>void PrintPending(sigset_t* pend){int i = 0;for (i = 1; i < 32; ++i){if (sigismember(pend, i)){printf("1");}else{printf("0");}}printf("\n");}int main(){sigset_t set, oset;sigset_t pending;// 使用系统函数对信号集进行初始化sigemptyset(&set);sigemptyset(&oset);sigemptyset(&pending);// 阻塞2号信号// 先用系统函数对set信号集进行设置sigaddset(&set, 2);// 使用sigprocmask函数更改进程的信号屏蔽字// 第一个参数,三个选项:SIG_BLOCK(mask |= set) SIG_UNBLOCK(mask &= ~set) SIG_SETMASK(mask = set)sigprocmask(SIG_BLOCK, &set, &oset);int flag = 1; // 表示已经阻塞2号信号int count = 0;while (1){// 使用sigpending函数获取pending信号集 sigpending(&pending); // 打印pending位图 PrintPending(&pending); if (++count == 10){// 两种方法都可以sigprocmask(SIG_UNBLOCK, &set, &oset);//sigprocmask(SIG_SETMASK, &oset, NULL); }sleep(1);}return 0;}
运行结果如下:
文章插图
信号2被阻塞之后就变成了未决状态,当该信号从阻塞集合中解除的时候,该信号就会被处理,该信号被处理后 , 该信号的未决信号集的标志位将从1置为0 。
推荐阅读
- too同义词|too的同义词
- 二 SpringCloud - Eureka注册中心,feign远程调用,hystrix降级和熔断
- 焊工证个人信息查询入口 查询入口
- Docker在windows系统以及Linux系统的安装
- 二 京东云开发者| Redis数据结构-List、Hash、Set及Sorted Set的结构实现
- 一篇文章带你了解服务器操作系统——Linux简单入门
- 二、python基本数据类型
- 二 【SSM】学习笔记——SpringMVC入门
- 原神片剂深研第二关怎么通关
- 一步一图带你深入理解 Linux 虚拟内存管理