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;

}

clip_image002

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;

}