阻塞信号集和未决信号集:
例如:当进程收到SIGINT信号后,首先被保留在未决信号集中,此时标识位为1,当这个信号被处理之前,先检查阻塞信号集中对应的编号的位上的标识是否为1;
为1表示该信号被当前进程阻塞了,此时该信号暂时不被处理,对应的标识仍然为1
为0表示该信号没有被当前进程阻塞,则未决信号集的这个信号需要被处理(忽略,执行默认动作,执行用户自定义函数),当信号被处理完成后,未决信号集中这个信号的标识从1变0,说明该信号已经抵达(被处理)
加入该信号在阻塞的使用产生多次,未决信号集标识位仍为1,在解除对该信号的阻塞后,此信号只被处理一次
信号集相关函数:
int sigemptyset(sigset_t *set);
函数说明:将某个信号集清0(信号集的信号都变0)
返回值:成功返回0,失败-1
int sigfillset(sigset_t *set);
函数说明:将某个信号集置1
返回值:成功返回0,失败-1
int sigaddset(sigset_t *set,int signum);
函数说明:将某个函数加入到信号集中
返回值:成功返回0,失败-1
int sigdelset(sigset_t *set,int signum);
函数说明:将某个函数从信号集中移除
返回值:成功返回0,失败-1
int sigismember(const sigset_t *set,int signum);
函数说明:判断某个信号是否在信号集中
函数返回值:在->1;不在->0;出错->-1
sigprocmask函数:
函数原型: int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how参数:
SIG_BLOCK
The set of blocked signals is the union of the current set and
the set argument.(将某个信号集的所有为1的信号设置为阻塞)
SIG_UNBLOCK
The signals in set are removed from the current set of blocked
signals. It is permissible to attempt to unblock a signal which
is not blocked.((将某个信号集的所有为1的信号从阻塞信号集移除)
SIG_SETMASK
The set of blocked signals is set to the argument set.
set参数:
传入参数,是一个自定义信号集合。
oldset参数:
传出参数,保存旧的信号屏蔽字
sigpending函数:
函数原型:int sigpending(sigset_t *set);函数说明:读取当前进程的未决信号集,将未决信号集拷贝到自定义信号集(set)中
函数参数:set 传出参数
函数返回值:成功返回0,失败返回-1
测试:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include <signal.h>
#include <sys/time.h>
void handler(int signo)
{
printf("signo==[%d]\n",signo);
}
int main()
{
signal(SIGINT,handler);//不同信号可以用同一个信号处理函数
signal(SIGQUIT,handler);
sigset_t set;
//初始化,全部置0
sigemptyset(&set);
//让set信号集的SIGINT,SIGQUIT信号位变1
sigaddset(&set,SIGINT);
sigaddset(&set,SIGQUIT);
// int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
//将set信号集中位为1的信号加入阻塞信号集
sigprocmask(SIG_BLOCK,&set,NULL);
int i=0;
int j=1;
sigset_t pend;//定义一个传出信号集,获取未决信号集
while(1)
{
sigemptyset(&pend);//初始化
sigpending(&pend);//获取未决信号集
for(i=1;i<32;i++)打印1到32编号信号是否在未决信号集中
{
if(sigismember(&pend,i)==1)
{
printf("1");//存在打印1
}
else if(sigismember(&pend,i)==0)
{
printf("0");
}
}
printf("\n");
if(j++%5==0)//每5次将set信号集中位为1的信号从阻塞信号集中移除
{
sigprocmask(SIG_UNBLOCK,&set,NULL);
}
else //除了5的倍数次继续将set信号集中位为1的信号加入阻塞信号集
{
sigprocmask(SIG_BLOCK,&set,NULL);
}
sleep(1);
}
return 0;
}
结果:
我们从结果可以发现未决信号集中的信号并不会叠加,不管在阻塞状态下发送多少次信号,每五次只会执行一次,然后这两个信号在未决信号区中也不存在了。接下来又把他们加入到阻塞信号集。