天天看點

sigprocmask 阻塞程序

1、有時候不希望在接到信号時就立即停止目前執行,去處理信号,同時也不希望忽略該信号,而是延時一段時間去調用信号處理函數。這種情況是通過阻塞信号實作的。

2、信号阻塞和忽略信号的差別。

阻塞的概念和忽略信号是不同的。作業系統在信号被程序解除阻塞之前不會講信号傳遞出去,被阻塞的信号也不會影響程序的行為,信号隻是暫時被阻止傳遞。當程序忽略一個信号時,信号會被傳遞出去但程序會将信号丢棄。

3、信号阻塞系統調用,它們的都起到阻塞的作用,它們不是協作使用的。

#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示例(示範添加信号掩碼):

#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 阻塞程式

sigprocmask示例(示範添某部分代碼不被信号打攪):

#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");
}




本系列文章由muge0913編寫,轉載請注明出處:http://blog.csdn.net/muge0913/article/details/7334771
           

繼續閱讀