/*
sigsuspend的使用
sigprocmask和pause连起来用可以实现sigsuspend的功能;但是还是使用sigsuspend函数,应为sigsuspend是原子操作
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
volatile sig_atomic_t quitflag;
static void sig_handler(int signo)
{
if(signo==SIGINT)
{
printf("ninterruptn/n");
}
else if(signo==SIGQUIT)
{
quitflag=1;
printf("/n SIGQUIT quitflag =1/n");
}
else if(signo==SIGALRM)
{
printf("/n SIGALRM /n");
}
printf("/n other sig /n");
}
//void handlers()
//{
// printf("/n alarm SIGALRM/n");
//}
int main(int argc,char * argv[])
{
sigset_t newmask,oldmask,zeromask;
if(signal(SIGINT,sig_handler)==SIG_ERR)
{
perror("signal(SIGINT) ERROR");
}
if(signal(SIGQUIT,sig_handler)==SIG_ERR)
{
perror("signal(SIGQUIT) error");
}
if(signal(SIGALRM,sig_handler)==SIG_ERR)
{
perror("signal(SIGALRM) erro");
}
sigemptyset(&newmask);
sigemptyset(&zeromask);
sigaddset(&newmask,SIGQUIT);
if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)!=0)
{
perror("sigpromask SIG_BLOCK error");
}
while(quitflag==0)//while(1)
{
//alarm(1);
if(sigismember(&zeromask,SIGQUIT))//检查挂起信号集合中是否有SIGQUIT
{
printf("/nzeromask SIGQUIT pending/n");
}
if(sigismember(&newmask,SIGQUIT))//检查挂起信号集合中是否有SIGQUIT
{
printf("/nnewmask SIGQUIT pending/n");
}
if(sigismember(&oldmask,SIGQUIT))//检查挂起信号集合中是否有SIGQUIT
{
printf("/oldmask SIGQUIT pending/n");
}
if(sigismember(&zeromask,SIGALRM))//检查挂起信号集合中是否有SIGALRM
{
printf("/nzeromask SIGALRM pending/n");
}
if(sigismember(&newmask,SIGALRM))//检查挂起信号集合中是否有SIGALRM
{
printf("/nnewmask SIGALRM pending/n");
}
if(sigismember(&oldmask,SIGALRM))//检查挂起信号集合中是否有SIGALRM
{
printf("/oldmask SIGALRM pending/n");
}
sigsuspend(&newmask);
if(sigismember(&zeromask,SIGQUIT))//检查挂起信号集合中是否有SIGQUIT
{
printf("/nzeromask 2 SIGQUIT pending/n");
}
if(sigismember(&newmask,SIGQUIT))//检查挂起信号集合中是否有SIGQUIT
{
printf("/nnewmask 2 SIGQUIT pending/n");
}
if(sigismember(&oldmask,SIGQUIT))//检查挂起信号集合中是否有SIGQUIT
{
printf("/oldmask 2 SIGQUIT pending/n");
}
if(sigismember(&zeromask,SIGALRM))//检查挂起信号集合中是否有SIGALRM
{
printf("/nzeromask 2 SIGALRM pending/n");
}
if(sigismember(&newmask,SIGALRM))//检查挂起信号集合中是否有SIGALRM
{
printf("/nnewmask 2 SIGALRM pending/n");
}
if(sigismember(&oldmask,SIGALRM))//检查挂起信号集合中是否有SIGALRM
{
printf("/oldmask 2 SIGALRM pending/n");
}
}
quitflag = 0;
if(sigprocmask(SIG_SETMASK,&oldmask,NULL)!=0)
{
perror("sigpromask SIG_SETMASK error");
}
exit(0);
}
//分析:1.1:当while(1)时,sigsuspend设置新的mask,收到信号恢复原先的mask(即是zeromask,他没有包含SIGQUIT),然后调用信号处理函数,等待信号处理函数返回后,sigsuspend再返回。
//1.2: 当while(quitflag==0)时,ctrl+c有反应,sigsuspend返回后仍再while函数中循环。当输入ctrl+/时,sigsuspend返回后quitflag=1,跳出while循环拉。
//2:sigsuspend保存当前的信号屏蔽字(有信号屏蔽字就保存有的mask,没有信号屏蔽字的就保存没有信号屏蔽字的mask;这里的mask就是传递到sigsuspend中的参数。)当sigsuspend处理完信号后,就恢复传递到sigsuspend中参数的信号集。所以sigsuspend中的参数和sigsuspend要处理的信号没关系。
/*
备注:
sigsuspend是一个原子操作,包含4个步骤:
(1) 设置新的mask阻塞当前进程;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数;
(4) 待信号处理函数返回后,sigsuspend返回。
*/
sigsuspend的理解
最新推荐文章于 2023-10-06 19:57:57 发布