您的位置:首页 > 运维架构 > Linux

那年,一步一步学linux c ---sigprocmask 阻塞进程

2014-06-10 22:04 471 查看
本系列文章由muge0913编写,转载请注明出处:http://blog.csdn.net/muge0913/article/details/7334771



1、有时候不希望在接到信号时就立即停止当前执行,去处理信号,同时也不希望忽略该信号,而是延时一段时间去调用信号处理函数。这种情况是通过阻塞信号实现的。

 

2、信号阻塞和忽略信号的区别。

阻塞的概念和忽略信号是不同的。操作系统在信号被进程解除阻塞之前不会讲信号传递出去,被阻塞的信号也不会影响进程的行为,信号只是暂时被阻止传递。当进程忽略一个信号时,信号会被传递出去但进程会将信号丢弃。
 

3、信号阻塞系统调用,它们的都起到阻塞的作用,它们不是协作使用的。

[cpp] view
plaincopyprint?

#include <signal.h>  

  

int sigprocmask(ubt how,const sigset_t*set,sigset_t *oldset);  

  

int sigsuspend(const sigset_t*sigmask);  

sigprocmask设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞)。

参数:

how:用于指定信号修改的方式,可能选择有三种

SIG_BLOCK//将set所指向的信号集中包含的信号加到当前的信号掩码中。即信号掩码和set信号集进行或操作。

SIG_UNBLOCK//将set所指向的信号集中包含的信号从当前的信号掩码中删除。即信号掩码和set进行与操作。

SIG_SETMASK //将set的值设定为新的进程信号掩码。即set对信号掩码进行了赋值操作。

 

set:为指向信号集的指针,在此专指新设的信号集,如果仅想读取现在的屏蔽值,可将其置为NULL。

oldset:也是指向信号集的指针,在此存放原来的信号集。可用来检测信号掩码中存在什么信号。

返回说明:

成功执行时,返回0。失败返回-1,errno被设为EINVAL。

 

sigprocmask示例(演示添加信号掩码):

[cpp] view
plaincopyprint?

#include <stdio.h>  

#include <signal.h>  

void checkset();  

  

void main()  

{  

     sigset_tblockset;  

     sigemptyset(&blockset);  

     sigaddset(&blockset,SIGINT);  

     sigaddset(&blockset,SIGTSTP);  

  

     checkset();  

  

     sigprocmask(SIG_SETMASK,&blockset,NULL);  

     checkset();  

  

     sigaddset(&blockset,SIGTERM);  

     sigprocmask(SIG_BLOCK,&blockset,NULL);  

     checkset();  

  

     sigdelset(&blockset,SIGTERM);  

     sigprocmask(SIG_UNBLOCK,&blockset,NULL);  

     checkset();  

}  

  

void checkset()  

{  

  

     sigset_tset set;  

     printf("checksetstart:\n");  

  

     if(sigprocmask(0,NULL,&set)<0)  

     {  

     printf("checksetsigprocmask error!!\n");  

     exit(0);  

     }  

  

     if(sigismember(&set,SIGINT))  

     printf("sigint\n");  

     if(sigismember(&set,SIGTSTP))  

     printf("sigtstp\n");  

  

     if(sigismember(&set,SIGTERM))  

     printf("sigterm\n");  

      printf("checksetend\n");  

}  



sigprocmask示例(演示添某部分代码不被信号打搅):

 

[cpp] view
plaincopyprint?

#include <stdio.h>  

#include <signal.h>  

void checkset();  

  

void func();  

void main()  

{  

     sigset_tblockset,oldblockset,pendmask;  

     printf("pid:%ld\n",(long)getpid());  

  

     signal(SIGINT,func); //信号量捕捉函数,捕捉到SIGINT,跳转到函数指针func处执行  

  

    sigemptyset(&blockset); //初始化信号量集  

    sigaddset(&blockset,SIGTSTP); //将SIGTSTP添加到信号量集中  

    sigaddset(&blockset,SIGINT);//将SIGINT添加到信号量集中  

  

   sigprocmask(SIG_SETMASK,&blockset,&oldblockset); //将blockset中的SIGINT,SIGTSTP阻塞掉,并保存当前信号屏蔽字  

  

     /*执行以下程序时,不会被信号打搅*/  

    checkset();  

    sleep(5);  

     sigpending(&pendmask); //检查信号是悬而未决的  

     if(sigismember(&pendmask,SIGINT)) //SIGINT是悬而未决的。所谓悬而未决,是指SIGQUIT被阻塞还没有被处理  

         printf("SIGINTpending\n");  

  

     /*免打搅结束*/  

  

     sigprocmask(SIG_SETMASK,&oldblockset,NULL); //恢复被屏蔽的信号SIGINT SIGTSTP  

     printf("SIGINTunblocked\n");  

     sleep(6);  

}  

  

void checkset()  

{  

     sigset_tset;  

     printf("checksetstart:\n");  

     if(sigprocmask(0,NULL,&set)<0)  

     {  

     printf("checksetsigprocmask error!!\n");  

     exit(0);  

     }  

     if(sigismember(&set,SIGINT))  

     printf("sigint\n");  

  

     if(sigismember(&set,SIGTSTP))  

     printf("sigtstp\n");  

  

     if(sigismember(&set,SIGTERM))  

     printf("sigterm\n");  

  

     printf("checksetend\n");  

  

}  

void func()  

{  

     printf("hellofunc\n");  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  sigprocmask