1.1. sigprocmask信号阻塞
函数sigaction中设置的被阻塞信号集合只是针对于要处理的信号,例如
struct sigaction act;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,SIGQUIT);
sigaction(SIGINT,&act,NULL);
表示只有在处理信号SIGINT时,才阻塞信号SIGQUIT;
函数sigprocmask是全程阻塞,在sigprocmask中设置了阻塞集合后,被阻塞的信号将不能再被信号处理函数捕捉,直到重新设置阻塞信号集合。
原型为:
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
参数how的值为如下3者之一:
a:SIG_BLOCK ,将参数2的信号集合添加到进程原有的阻塞信号集合中
b:SIG_UNBLOCK ,从进程原有的阻塞信号集合移除参数2中包含的信号
c:SIG_SETMASK,重新设置进程的阻塞信号集为参数2的信号集
参数set为阻塞信号集
参数oldset是传出参数,存放进程原有的信号集,通常为NULL
示例:添加全程阻塞
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
int g_iSeq=0;
void SignHandlerNew(int iSignNo,siginfo_t *pInfo,void *pReserved)
{
int iSeq=g_iSeq++;
printf("%d Enter SignHandlerNew,signo:%d\n",iSeq,iSignNo);
sleep(3);
printf("%d Leave SignHandlerNew,signo:%d\n",iSeq,iSignNo);
}
int main()
{
char szBuf[8];
int iRet;
//屏蔽掉SIGQUIT信号
sigset_t sigSet;
sigemptyset(&sigSet);
sigaddset(&sigSet,SIGQUIT);
sigprocmask(SIG_BLOCK,&sigSet,NULL);
struct sigaction act;
act.sa_sigaction=SignHandlerNew;
act.sa_flags=SA_SIGINFO;
sigemptyset(&act.sa_mask);
sigaction(SIGINT,&act,NULL);
while(1);
return 0;
}
实例:取消指定信号的全程阻塞。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
int g_iSeq=0;
void SignHandlerNew(int iSignNo,siginfo_t *pInfo,void *pReserved)
{
int iSeq=g_iSeq++;
printf("%d Enter SignHandlerNew,signo:%d\n",iSeq,iSignNo);
sleep(3);
printf("%d Leave SignHandlerNew,signo:%d\n",iSeq,iSignNo);
}
int main()
{
//屏蔽掉SIGINT和SIGQUIT信号,SigHandlerNew将不能再捕捉SIGINT和SIGQUIT
sigset_t sigSet;
sigemptyset(&sigSet);
sigaddset(&sigSet,SIGINT);
sigaddset(&sigSet,SIGQUIT);
sigprocmask(SIG_BLOCK,&sigSet,NULL);//将SIGINT、SIGQUIT屏蔽
struct sigaction act;
act.sa_sigaction=SignHandlerNew;
act.sa_flags=SA_SIGINFO;
sigemptyset(&act.sa_mask);
sigaction(SIGINT,&act,NULL);
sigaction(SIGQUIT,&act,NULL);
int iCount = 0;
while(1)
{
if(iCount > 3)
{
sigset_t sigSet2;
sigemptyset(&sigSet2);
sigaddset(&sigSet2, SIGINT);
sigprocmask(SIG_UNBLOCK, &sigSet2, NULL);
}
iCount ++;
sleep(2);
}
return 0;
}
Example3:利用sigpending测试信号,并采用上图的模型
#include <signal.h>
#include <unistd.h>
void handler(int signum, siginfo_t* pInfo, void* pReversed)
{
printf("receive signal %d \n",signum);
}
int main()
{
sigset_t new_mask, old_mask, pending_mask;
sigemptyset(&new_mask);
sigaddset(&new_mask, SIGINT);
if(sigprocmask(SIG_BLOCK, &new_mask, &old_mask))
printf("block signal SIGINT error\n");
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = handler;
if(sigaction(SIGINT, &act, NULL))
printf("install signal SIGINT error\n");
sleep(10);
printf("now begin to get pending mask and unblock SIGINT\n");
if(sigpending(&pending_mask) < 0)//将阻塞信号全部添加到pending_mask信号集中并返回
printf("get pending mask error\n");
if(sigismember(&pending_mask, SIGINT))
printf("signal SIGINT is pending\n");
if(sigprocmask(SIG_SETMASK, &old_mask, NULL) < 0)
printf("unblock signal error\n");
printf("signal unblocked\n");
sleep(10);
return 0;
}