實(shí)時(shí)信號(hào)和非實(shí)時(shí)信號(hào)_第1頁
實(shí)時(shí)信號(hào)和非實(shí)時(shí)信號(hào)_第2頁
實(shí)時(shí)信號(hào)和非實(shí)時(shí)信號(hào)_第3頁
實(shí)時(shí)信號(hào)和非實(shí)時(shí)信號(hào)_第4頁
實(shí)時(shí)信號(hào)和非實(shí)時(shí)信號(hào)_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、 實(shí)時(shí)信號(hào)之所以是可靠的,因?yàn)樵谶M(jìn)程阻塞該信號(hào)的時(shí)間內(nèi),發(fā)給該進(jìn)程的所有實(shí)時(shí)信號(hào)會(huì)排隊(duì),而非實(shí)時(shí)信號(hào)則會(huì)合并為一個(gè)信號(hào)。早期的kill函數(shù)只能向特定的進(jìn)程發(fā)送一個(gè)特定的信號(hào),并且早期的信號(hào)處理函數(shù)也不能接受附加數(shù)據(jù)。siqueue和sigaction解決了這個(gè)問題。平時(shí)沒有有機(jī)會(huì)使用實(shí)時(shí)信號(hào),所以想體驗(yàn)下它的排隊(duì)特性。       下面這個(gè)例子中,進(jìn)程先屏蔽SIGINT和SIGRTMIN兩個(gè)信號(hào),其中SIGINT是非實(shí)時(shí)信號(hào),而SIGRTMIN為實(shí)時(shí)信號(hào),接著進(jìn)程睡眠,睡眠完成之后再接觸對(duì)這兩個(gè)信號(hào)的屏蔽,此時(shí)可以比較對(duì)兩種

2、信號(hào)的處理方式是否一樣。#include <stdio.h>#include <string.h>#include <signal.h>#include <unistd.h>void sig_handler(int,siginfo_t*,void*);int main(int argc,char*argv)   struct sigaction act;   sigset_t newmask, oldmask;   int rc;      sig

3、emptyset(&newmask);   /往信號(hào)集中添加一個(gè)非實(shí)時(shí)信號(hào)   sigaddset(&newmask, SIGINT);   /往信號(hào)集中添加一個(gè)實(shí)時(shí)信號(hào)   sigaddset(&newmask, SIGRTMIN);   /屏蔽實(shí)時(shí)信號(hào)SIGRTMIN   sigprocmask(SIG_BLOCK, &newmask, &oldmask);   act.sa_sigaction = sig_ha

4、ndler;   act.sa_flags = SA_SIGINFO;   if(sigaction(SIGINT, &act, NULL) < 0)          printf("install sigal errorn");      if(sigaction(SIGRTMIN, &act, NULL) < 0)        &#

5、160; printf("install sigal errorn");      printf("pid = %dn", getpid();      /進(jìn)程睡眠,在此時(shí)間內(nèi)的發(fā)給該進(jìn)程的所有實(shí)時(shí)信號(hào)   /將排隊(duì),不會(huì)有信號(hào)丟失   sleep(20);      /解除對(duì)SIGRTMIN信號(hào)的屏蔽   /信號(hào)處理函數(shù)將會(huì)被調(diào)用   sigprocmas

6、k(SIG_SETMASK, &oldmask, NULL);   return 0;void sig_handler(int signum,siginfo_t *info,void *myact)   if(signum = SIGINT)       printf("Got a common signaln");   else       printf("Got a real time sign

7、aln");將程序編譯好之后,再開一個(gè)終端用于發(fā)送實(shí)時(shí)信號(hào)。ecyecy-geek:/pthreads$ ./sigqueue_receive pid = 8871進(jìn)程開始睡眠在新的終端輸入:ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871連續(xù)發(fā)送四個(gè)SIGRTMIN,接著回到之前的終端,連續(xù)四次按下

8、"ctrl+c"。CCCC最后進(jìn)程終于醒來,整個(gè)輸出如下:pid = 8871CCCCGot a real time signalGot a real time signalGot a real time signalGot a real time signalGot a common signal果然接受到四個(gè)實(shí)時(shí)信號(hào),并且四次調(diào)用了信號(hào)處理函數(shù),而對(duì)于SIGINT,雖然也按下了四次"ctrl+c",但是進(jìn)程對(duì)其只做一次處理。我發(fā)現(xiàn)這兒有個(gè)細(xì)節(jié)有點(diǎn)意思,這個(gè)例子中是先發(fā)實(shí)時(shí)信號(hào)后發(fā)非實(shí)時(shí)信號(hào),所以信號(hào)處理函數(shù)先處理實(shí)時(shí)信號(hào),如果只是按照順序注冊信號(hào)的話

9、,這很好理解,但是換一下,先按下了四次"ctrl+c"然后使用kill發(fā)四次實(shí)時(shí)信號(hào),結(jié)果發(fā)現(xiàn)輸出的結(jié)果仍然一樣,這就有點(diǎn)怪了,這說明實(shí)時(shí)信號(hào)的優(yōu)先級(jí)比非實(shí)時(shí)信號(hào)要高,內(nèi)核每個(gè)進(jìn)程的信號(hào)組成一個(gè)雙向鏈表,實(shí)時(shí)信號(hào)插入的時(shí)候就不是隨便插在尾部了。哎,不懂內(nèi)核什么都要靠猜測,不爽在網(wǎng)上找到這樣一段話: 信號(hào)的優(yōu)先級(jí):信號(hào)實(shí)質(zhì)上是軟中斷,中斷有優(yōu)先級(jí),信號(hào)也有優(yōu)先級(jí)。如果一個(gè)進(jìn)程有多個(gè)未決信號(hào),則對(duì)于同一個(gè)未決的實(shí)時(shí)信號(hào),內(nèi)核將按照發(fā)送的順序來遞送信號(hào)。如果存在多個(gè)未決的實(shí)時(shí)信號(hào),則值(或者說編號(hào))越小的越先被遞送。如果既存在不可靠信號(hào),又存在可靠信號(hào)(實(shí)時(shí)信號(hào)),雖然POSIX

10、對(duì)這一情況沒有明確規(guī) 定,但Linux系統(tǒng)和大多數(shù)遵循POSIX標(biāo)準(zhǔn)的操作系統(tǒng)一樣,將優(yōu)先遞送不可靠信號(hào)。經(jīng)過我反反復(fù)復(fù)地試驗(yàn),我發(fā)現(xiàn)實(shí)驗(yàn)結(jié)果和上面描述的剛好相反,信號(hào)的編號(hào)越大越先被遞送,一個(gè)進(jìn)程如果處理SIGQUIT(3),SIGINT(2),SIGHUP(1)(通過"kill -l"可以查看信號(hào)的編號(hào)),那么先后給該進(jìn)程發(fā)送SIGINT,SIGHUP,SIGQUIT,處理的順序會(huì)是SIGQUIT,SIGINT,SIGHUP,不論改變這個(gè)三個(gè)信號(hào)的發(fā)送順序,處理的順序都是一樣的。信號(hào)詳解 博客分類: · linux linuxsignal 一 信號(hào)的

11、種類可靠信號(hào)與不可靠信號(hào), 實(shí)時(shí)信號(hào)與非實(shí)時(shí)信號(hào)可靠信號(hào)就是實(shí)時(shí)信號(hào), 那些從UNIX系統(tǒng)繼承過來的信號(hào)都是非可靠信號(hào), 表現(xiàn)在信號(hào)不支持排隊(duì),信號(hào)可能會(huì)丟失, 比如發(fā)送多次相同的信號(hào), 進(jìn)程只能收到一次. 信號(hào)值小于SIGRTMIN的都是非可靠信號(hào).非可靠信號(hào)就是非實(shí)時(shí)信號(hào), 后來, Linux改進(jìn)了信號(hào)機(jī)制, 增加了32種新的信號(hào), 這些信號(hào)都是可靠信號(hào), 表現(xiàn)在信號(hào)支持排隊(duì), 不會(huì)丟失, 發(fā)多少次, 就可以收到多少次. 信號(hào)值位于 SIGRTMIN, SIGRTMAX 區(qū)間的都是可靠信號(hào). 關(guān)于可靠信號(hào), 還可以參考WIKI的一段話: Text代碼 

12、0;1. The real-time signals, ranging from SIGRTMIN to SIGRTMAX, are a set of signals that can be used for application-defined purposes.   2. Because SIGRTMIN may have different

13、 values on different Unix-like systems, applications should always refer to the signals in the form SIGRTMIN+n, where n is a constant integer expression.   3. The real-ti

14、me signals have a number of properties that differentiate them from other signals and make them suitable for application-defined purposes:   4. * Multiple instances of a 

15、real-time signal can be sent to a process and all will be delivered.   5. * Real-time signals can be accompanied by an integer or pointer value (see sigqueue2). 

16、0; 6. * Real-time signals are guaranteed to be delivered in the order they were emitted.  The real-time signals, ranging from SIGRTMIN to SIGRTMAX, are a set of signals that can be used for application-defined purposes.B

17、ecause SIGRTMIN may have different values on different Unix-like systems, applications should always refer to the signals in the form SIGRTMIN+n, where n is a constant integer expression.The real-time signals have a number of properties that differentiate them from other signals and make them suitab

18、le for application-defined purposes:* Multiple instances of a real-time signal can be sent to a process and all will be delivered.* Real-time signals can be accompanied by an integer or pointer value (see sigqueue2).* Real-time signals are guaranteed to be delivered in the order they were emitted.&#

19、160; 命令行輸入 kill -l, 可以列出系統(tǒng)支持的所有信號(hào): C代碼  1. > kill -l   2.  1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP   3.  6) SIGABRT  7) SIGBUS&#

20、160;  8) SIGFPE   9) SIGKILL 10) SIGUSR1   4. 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM   5. 16) SIGSTKFLT   17) SIGCHLD 18) SIGCONT 

21、;19) SIGSTOP 20) SIGTSTP   6. 21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU 25) SIGXFSZ   7. 26) SIGVTALRM   27) SIGPROF 28) SIGWINCH    29) SIGIO &

22、#160; 30) SIGPWR   8. 31) SIGSYS  34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3   9. 38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  

23、41) SIGRTMIN+7  42) SIGRTMIN+8   10. 43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13   11. 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) 

24、SIGRTMAX-13 52) SIGRTMAX-12   12. 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7   13. 58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61)

25、 SIGRTMAX-3  62) SIGRTMAX-2   14. 63) SIGRTMAX-1  64) SIGRTMAX      > kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL10) SIGUSR111) SIGSEGV12) SIGUSR213) SIGPIPE14

26、) SIGALRM15) SIGTERM16) SIGSTKFLT17) SIGCHLD18) SIGCONT19) SIGSTOP20) SIGTSTP21) SIGTTIN22) SIGTTOU23) SIGURG24) SIGXCPU25) SIGXFSZ26) SIGVTALRM27) SIGPROF28) SIGWINCH29) SIGIO30) SIGPWR31) SIGSYS34) SIGRTMIN35) SIGRTMIN+136) SIGRTMIN+237) SIGRTMIN+338) SIGRTMIN+439) SIGRTMIN+540) SIGRTMIN+641) SIGR

27、TMIN+742) SIGRTMIN+843) SIGRTMIN+944) SIGRTMIN+1045) SIGRTMIN+1146) SIGRTMIN+1247) SIGRTMIN+1348) SIGRTMIN+1449) SIGRTMIN+1550) SIGRTMAX-1451) SIGRTMAX-1352) SIGRTMAX-1253) SIGRTMAX-1154) SIGRTMAX-1055) SIGRTMAX-956) SIGRTMAX-857) SIGRTMAX-758) SIGRTMAX-659) SIGRTMAX-560) SIGRTMAX-461) SIGRTMAX-362)

28、 SIGRTMAX-263) SIGRTMAX-164) SIGRTMAX非可靠信號(hào)一般都有確定的用途及含義,  可靠信號(hào)則可以讓用戶自定義使用 二 信號(hào)的安裝 早期的Linux使用系統(tǒng)調(diào)用 signal 來安裝信號(hào)#include <signal.h>void (*signal(int signum, void (*handler)(int)(int); 該函數(shù)有兩個(gè)參數(shù), signum指定要安裝的信號(hào), handler指定信號(hào)的處理函數(shù).該函數(shù)的返回值是一個(gè)函數(shù)指針, 指向上次安裝的handler經(jīng)典安裝方式:if (signal(SIG

29、INT, SIG_IGN) != SIG_IGN)     signal(SIGINT, sig_handler);先獲得上次的handler, 如果不是忽略信號(hào), 就安裝此信號(hào)的handler由于信號(hào)被交付后, 系統(tǒng)自動(dòng)的重置handler為默認(rèn)動(dòng)作, 為了使信號(hào)在handler處理期間, 仍能對(duì)后繼信號(hào)做出反應(yīng), 往往在handler的第一條語句再次調(diào)用 signalsig_handler(ing signum)     /* 重新安裝信號(hào) */    signal(signum, sig_handler);  

30、0; .我們知道在程序的任意執(zhí)行點(diǎn)上, 信號(hào)隨時(shí)可能發(fā)生, 如果信號(hào)在sig_handler重新安裝信號(hào)之前產(chǎn)生, 這次信號(hào)就會(huì)執(zhí)行默認(rèn)動(dòng)作, 而不是sig_handler. 這種問題是不可預(yù)料的.使用庫函數(shù) sigaction  來安裝信號(hào)為了克服非可靠信號(hào)并同一SVR4和BSD之間的差異, 產(chǎn)生了 POSIX 信號(hào)安裝方式, 使用sigaction安裝信號(hào)的動(dòng)作后, 該動(dòng)作就一直保持, 直到另一次調(diào)用 sigaction建立另一個(gè)動(dòng)作為止. 這就克服了古老的 signal 調(diào)用存在的問題#include <signal.h> int sigaction(in

31、t signum,const struct sigaction *act,struct sigaction *oldact);經(jīng)典安裝方式:struct sigaction action, old_action;/* 設(shè)置SIGINT */action.sa_handler = sig_handler;sigemptyset(&action.sa_mask);sigaddset(&action.sa_mask, SIGTERM);action.sa_flags = 0;/* 獲取上次的handler, 如果不是忽略動(dòng)作, 則安裝信號(hào) */sigaction(SIGINT, NU

32、LL, &old_action);if (old_action.sa_handler != SIG_IGN)     sigaction(SIGINT, &action, NULL);基于 sigaction 實(shí)現(xiàn)的庫函數(shù): signalsigaction 自然強(qiáng)大, 但安裝信號(hào)很繁瑣, 目前l(fā)inux中的signal()是通過sigation()函數(shù)實(shí)現(xiàn)的,因此,即使通過signal()安裝的信號(hào),在信號(hào)處理函數(shù)的結(jié)尾也不必再調(diào)用一次信號(hào)安裝函數(shù)。 三 如何屏蔽信號(hào) 所謂屏蔽, 并不是禁止遞送信號(hào), 而是暫時(shí)阻塞信號(hào)的遞送,&

33、#160;解除屏蔽后, 信號(hào)將被遞送, 不會(huì)丟失. 相關(guān)API為int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set, int signum);int sigdelset(sigset_t *set, int signum);int sigismember(const sigset_t *set, int signum);int sigsuspend(const sigset_t *mask);int sigpending(sigset_t *set);-int 

34、0;sigprocmask(int  how,  const  sigset_t *set, sigset_t *oldset);sigprocmask()函數(shù)能夠根據(jù)參數(shù)how來實(shí)現(xiàn)對(duì)信號(hào)集的操作,操作主要有三種:* SIG_BLOCK在進(jìn)程當(dāng)前阻塞信號(hào)集中添加set指向信號(hào)集中的信號(hào)* SIG_UNBLOCK如果進(jìn)程阻塞信號(hào)集中包含set指向信號(hào)集中的信號(hào),則解除   對(duì)該信號(hào)的阻塞* SIG_SETMASK更新進(jìn)程阻塞信號(hào)集為set指向的信號(hào)集屏蔽整個(gè)進(jìn)程的信號(hào): C代碼  1. #include <s

35、ignal.h>   2. #include <stdio.h>   3. #include <stdlib.h>   4. #include <error.h>   5. #include <string.h>   6.   7. void sig_handler(int signum)   8.   9.  &

36、#160;  printf("catch SIGINTn");   10.   11.   12. int main(int argc, char *argv)   13.   14.     sigset_t block;   15.     struct sigaction 

37、action, old_action;   16.   17.     /* 安裝信號(hào) */  18.     action.sa_handler = sig_handler;   19.     sigemptyset(&action.sa_mask);   20.     ac

38、tion.sa_flags = 0;   21.   22.     sigaction(SIGINT, NULL, &old_action);   23.     if (old_action.sa_handler != SIG_IGN)    24.         

39、sigaction(SIGINT, &action, NULL);   25.        26.   27.     /* 屏蔽信號(hào) */  28.     sigemptyset(&block);   29.     sigaddset(&block, SIG

40、INT);   30.   31.     printf("block SIGINTn");   32.     sigprocmask(SIG_BLOCK, &block, NULL);   33.   34.     printf("-> send SIGINT ->

41、;n");   35.     kill(getpid(), SIGINT);   36.     printf("-> send SIGINT ->n");   37.     kill(getpid(), SIGINT);   38.     sleep(1);

42、  39.   40.     /* 解除信號(hào)后, 之前觸發(fā)的信號(hào)將被遞送,  41.      * 但SIGINT是非可靠信號(hào), 只會(huì)遞送一次  42.      */  43.     printf("unblock SIGINTn");   4

43、4.     sigprocmask(SIG_UNBLOCK, &block, NULL);   45.   46.     sleep(2);   47.   48.     return 0;   49.   #include <signal.h>#include <stdio.h>#incl

44、ude <stdlib.h>#include <error.h>#include <string.h>void sig_handler(int signum) printf("catch SIGINTn");int main(int argc, char *argv) sigset_t block; struct sigaction action, old_action; /* 安裝信號(hào) */ action.sa_handler = sig_handler; sigemptyset(&action.sa_mask); action

45、.sa_flags = 0; sigaction(SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGINT, &action, NULL); /* 屏蔽信號(hào) */ sigemptyset(&block); sigaddset(&block, SIGINT); printf("block SIGINTn"); sigprocmask(SIG_BLOCK, &block, NULL); printf("-> send

46、 SIGINT ->n"); kill(getpid(), SIGINT); printf("-> send SIGINT ->n"); kill(getpid(), SIGINT); sleep(1); /* 解除信號(hào)后, 之前觸發(fā)的信號(hào)將被遞送, * 但SIGINT是非可靠信號(hào), 只會(huì)遞送一次 */ printf("unblock SIGINTn"); sigprocmask(SIG_UNBLOCK, &block, NULL); sleep(2); return 0; 運(yùn)行結(jié)果: C代碼 &#

47、160;1. work> ./a.out    2. block SIGINT   3. -> send SIGINT ->   4. -> send SIGINT ->   5. unblock SIGINT   6. catch SIGINT  work> ./a.out block SIGINT-> send SIGIN

48、T ->-> send SIGINT ->unblock SIGINTcatch SIGINT這里發(fā)送了兩次SIGINT信號(hào) 可以看到, 屏蔽掉SIGINT后, 信號(hào)無法遞送, 解除屏蔽后, 才遞送信號(hào), 但只被遞送一次,因?yàn)镾IGINT是非可靠信號(hào), 不支持排隊(duì).只在信號(hào)處理期間, 屏蔽其它信號(hào)在信號(hào)的handler執(zhí)行期間, 系統(tǒng)將自動(dòng)屏蔽此信號(hào), 但如果還想屏蔽其它信號(hào)怎么辦?  可以利用 struct sigaction 結(jié)構(gòu)體的 sa_mask 屬性. C代碼  1. #include <signal.h> 

49、60; 2. #include <stdio.h>   3. #include <stdlib.h>   4. #include <error.h>   5. #include <string.h>   6.   7. void sig_handler(int signum)   8.   9.    

50、0;printf("in handle, SIGTERM is blockedn");   10.     /* 在此handler內(nèi)將屏蔽掉SIGTERM, 直到此handler返回 */  11.     printf("-> send SIGTERM ->n");   12.   

51、  kill(getpid(), SIGTERM);   13.     sleep(5);   14.     printf("handle donen");   15.   16.   17. void handle_term(int signum)   18.   19.  

52、0;  printf("catch sigterm and exit.n");   20.     exit(0);   21.   22.   23. int main(int argc, char *argv)   24.   25.     struct sigaction

53、 action, old_action;   26.   27.     /* 設(shè)置SIGINT */  28.     action.sa_handler = sig_handler;   29.     sigemptyset(&action.sa_mask);   30.   

54、0; /* 安裝handler的時(shí)候, 設(shè)置在handler  31.      * 執(zhí)行期間, 屏蔽掉SIGTERM信號(hào) */  32.     sigaddset(&action.sa_mask, SIGTERM);   33.     action.sa_flags = 0;   34. 

55、60; 35.     sigaction(SIGINT, NULL, &old_action);   36.     if (old_action.sa_handler != SIG_IGN)    37.         sigaction(SIGINT, &action, NULL);

56、  38.        39.   40.     /* 設(shè)置SIGTERM */  41.     action.sa_handler = handle_term;   42.     sigemptyset(&action.sa_mask);   43.  

57、;   action.sa_flags = 0;   44.   45.     sigaction(SIGTERM, NULL, &old_action);   46.     if (old_action.sa_handler != SIG_IGN)    47.     &#

58、160;   sigaction(SIGTERM, &action, NULL);   48.        49.   50.     printf("-> send SIGINT ->n");   51.     kill(getpid(), SIGINT); &#

59、160; 52.   53.     while (1)    54.         sleep(1);   55.        56.   57.     return 0;   58.   #include &l

60、t;signal.h>#include <stdio.h>#include <stdlib.h>#include <error.h>#include <string.h>void sig_handler(int signum) printf("in handle, SIGTERM is blockedn"); /* 在此handler內(nèi)將屏蔽掉SIGTERM, 直到此handler返回 */ printf("-> send SIGTERM ->n"); kill(getpid(), SIG

61、TERM); sleep(5); printf("handle donen");void handle_term(int signum) printf("catch sigterm and exit.n"); exit(0);int main(int argc, char *argv) struct sigaction action, old_action; /* 設(shè)置SIGINT */ action.sa_handler = sig_handler; sigemptyset(&action.sa_mask); /* 安裝handler的時(shí)候,

62、設(shè)置在handler * 執(zhí)行期間, 屏蔽掉SIGTERM信號(hào) */ sigaddset(&action.sa_mask, SIGTERM); action.sa_flags = 0; sigaction(SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGINT, &action, NULL); /* 設(shè)置SIGTERM */ action.sa_handler = handle_term; sigemptyset(&action.sa_mask); ac

63、tion.sa_flags = 0; sigaction(SIGTERM, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGTERM, &action, NULL); printf("-> send SIGINT ->n"); kill(getpid(), SIGINT); while (1) sleep(1); return 0; 運(yùn)行結(jié)果: C代碼  1. work> ./a.out  

64、0;2. -> send SIGINT ->   3. in handle, SIGTERM is blocked   4. -> send SIGTERM ->   5. handle done   6. catch sigterm and exit.  work> ./a.out-> send SIGINT ->

65、in handle, SIGTERM is blocked-> send SIGTERM ->handle donecatch sigterm and exit. 收到SIGINT后, 進(jìn)入sig_handler,此時(shí)發(fā)送SIGTERM信號(hào)將被屏蔽,  等sig_handler返回后, 才收到SIGTERM信號(hào), 然后退出程序  四 如何獲取未決信號(hào)所謂未決信號(hào), 是指被阻塞的信號(hào), 等待被遞送的信號(hào). int sigsuspend(const sigset_t *mask);sigpending(sigset_t *set)獲得當(dāng)

66、前已遞送到進(jìn)程,卻被阻塞的所有信號(hào),在set指向的信號(hào)集中返回結(jié)果。 C代碼  1. #include <signal.h>   2. #include <stdio.h>   3. #include <stdlib.h>   4. #include <error.h>   5. #include <string.h>   6.   7. /*&#

67、160;版本1, 可靠信號(hào)將被遞送多次 */  8. /#define MYSIGNAL SIGRTMIN+5   9. /* 版本2, 不可靠信號(hào)只被遞送一次 */  10. #define MYSIGNAL SIGTERM   11.   12. void sig_handler(int signum)   13.   14.  &#

68、160;  psignal(signum, "catch a signal");   15.   16.   17. int main(int argc, char *argv)   18.   19.     sigset_t block, pending;   20.    

69、 int sig, flag;   21.   22.     /* 設(shè)置信號(hào)的handler */  23.     signal(MYSIGNAL, sig_handler);   24.   25.     /* 屏蔽此信號(hào) */  26.   

70、0; sigemptyset(&block);   27.     sigaddset(&block, MYSIGNAL);   28.     printf("block signaln");   29.     sigprocmask(SIG_BLOCK, &block, NULL);   30. &

71、#160; 31.     /* 發(fā)兩次信號(hào), 看信號(hào)將會(huì)被觸發(fā)多少次 */  32.     printf("-> send a signal ->n");   33.     kill(getpid(), MYSIGNAL);   34.     pri

72、ntf("-> send a signal ->n");   35.     kill(getpid(), MYSIGNAL);   36.   37.     /* 檢查當(dāng)前的未決信號(hào) */  38.     flag = 0;   39.  &

73、#160;  sigpending(&pending);   40.     for (sig = 1; sig < NSIG; sig+)    41.         if (sigismember(&pending, sig)    42.  

74、0;          flag = 1;   43.             psignal(sig, "this signal is pending");   44.        &#

75、160;    45.        46.     if (flag = 0)    47.         printf("no pending signaln");   48.        49. &#

76、160; 50.     /* 解除此信號(hào)的屏蔽, 未決信號(hào)將被遞送 */  51.     printf("unblock signaln");   52.     sigprocmask(SIG_UNBLOCK, &block, NULL);   53.   54.   

77、60; /* 再次檢查未決信號(hào) */  55.     flag = 0;   56.     sigpending(&pending);   57.     for (sig = 1; sig < NSIG; sig+)    58.  

78、60;      if (sigismember(&pending, sig)    59.             flag = 1;   60.             psignal(sig,&#

79、160;"a pending signal");   61.             62.        63.     if (flag = 0)    64.         prin

80、tf("no pending signaln");   65.        66.   67.     return 0;   68.   #include <signal.h>#include <stdio.h>#include <stdlib.h>#include <error.h>#include <str

81、ing.h>/* 版本1, 可靠信號(hào)將被遞送多次 */#define MYSIGNAL SIGRTMIN+5/* 版本2, 不可靠信號(hào)只被遞送一次 */#define MYSIGNAL SIGTERMvoid sig_handler(int signum) psignal(signum, "catch a signal");int main(int argc, char *argv) sigset_t block, pending; int sig, flag; /* 設(shè)置信號(hào)的handler */ signal(MYSIGNAL, sig_handler); /*

82、屏蔽此信號(hào) */ sigemptyset(&block); sigaddset(&block, MYSIGNAL); printf("block signaln"); sigprocmask(SIG_BLOCK, &block, NULL); /* 發(fā)兩次信號(hào), 看信號(hào)將會(huì)被觸發(fā)多少次 */ printf("-> send a signal ->n"); kill(getpid(), MYSIGNAL); printf("-> send a signal ->n"); kill(getpid(), MYSIGNAL); /* 檢查當(dāng)前的未決信號(hào) */ flag = 0; sigpending(&pending); for (sig = 1; sig < NSIG; sig+) if (sigismember(&p

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論