本系列文章由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);
#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");
- }
#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");
- }