程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Linux下C編程:sigprocmask阻塞進程

Linux下C編程:sigprocmask阻塞進程

編輯:關於C語言

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示例(演示添某部分代碼不被信號打攪):

#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");     
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved