Linux下C編程:sigprocmask阻塞進程

來源:互聯網
上載者:User

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

查看全套文章:http://www.bianceng.cn/Programming/C/201212/34807.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.