1、信号集合的概述
在PCB中有两个非常重要的信号集。一个称之为“阻塞信号集”,另一个称之为“未决信号集”。 这两个信号集都是内核使用位图机制来实现的。但操作系统不允许我们直接对其进行位操作。而需自定义另外一个集合,借助信号集操作函数来对PCB中的这两个信号集进行修改
2、自定义信号集函数
sigset_t set,set即一个信号集。
#include<signal.h>
int sigemptyset(sigset_t *set); //将set集合置空
int sigfillset(sigset_t *set); //将所有信号加入set集合
int sigaddset(sigset_t *set, int signo); //将signo信号加入到set集合
int sigdelset(sigset_t *set, int signo); //从set集合中移除signo信号
int sigismember(const sigset_t*set,int signo);//判断信号是否存在
示例代码
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>
int main(int argc,char const*argv[]){
//定义一个信号集合
sigset_t set;
//清空信号集合
sigemptyset(&set);
//将SIGINT 加入set集合
sigaddset(&set, SIGINT);
//将SIGISTP 加入set集合
sigaddset(&set, SIGTSTP);
//判断SIGINT是否在set中
if (sigismember(&set, SIGINT))
{
printf("SIGINT在set集合中\n");
}
return 0;
}
3、信号屏蔽集(阻塞集)
信号阻塞集也称信号屏蔽集、信号掩码。每个进程都有一个阻塞集,创建子进程时子进程将继承父进程的阻塞集。
所谓阻塞并不是禁止传送信号, 而是暂缓信号的传送。
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,失败时错误代码只可能是 EINVAL,表示参数 how 不合法
示例代码
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>int main(int argc,char const*argv[])
{
//定义一个信号集合
sigset_t set;
//清空信号集合
sigemptyset(&set);
//将SIGINT 加入set集合
sigaddset(&set, SIGINT);
//将set集合添加到阻塞集中
sigprocmask(SIG_BLOCK, &set, NULL);
printf("5秒后SIGINT将从阻塞集中删除\n");
sleep(5);
//将set集合从阻塞集删除
sigprocmask(SIG_UNBLOCK, &set, NULL);
getchar();
return 0;
}
2、sigpending函数
#include<signal.h>
int sigpending(sigset_t *set);
功能:
读取当前进程的未决信号集
参数:
set:未决信号集
返回值:
成功:0
失败:-1
示例代码
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>
int main(int argc,char const*argv[])
{
#if1
//定义一个信号集合
sigset_t set;
//清空信号集合
sigemptyset(&set);
//将SIGINT 加入set集合
sigaddset(&set, SIGINT);
//将set集合添加到阻塞集中
sigprocmask(SIG_BLOCK, &set, NULL);
printf("5秒后判断SIGINT是否在未决信号集中\n");
sleep(5);
#endif
sigset_t set2;
sigemptyset(&set2);
sigpending(&set2);
if (sigismember(&set2, SIGINT))
{
printf("SIGINT在未决信号集中\n");
}
//将set集合从阻塞集删除
sigprocmask(SIG_UNBLOCK, &set, NULL);
return 0;
}
网友评论