国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

信號處理程序(signal handler)會被重置的信號

2024-06-28 13:20:58
字體:
來源:轉載
供稿:網友
信號處理程序(signal handler)會被重置的信號

  首先說明我的系統,CentOS 6.6,內核為2.6.32-504.12.2.el6.i686。

  當用signal對某個信號設定信號處理函數的時候,有些信號的處理函數會被重置,有些則不會,這種情況的具體說明我還沒有找到,這里我就先列一下我找到的幾個信號。

  信號處理程序會被重置的信號:

  1. SIGALRM

    比如下面這段代碼,這段代碼的作用就是給自己發送SIGALRM信號,直到發送了NUM次。

 1 #include <errno.h> 2 #include <pwd.h> 3 #include <signal.h> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <stdarg.h> 7 #include <stdio.h> 8 #include <sys/types.h> 9 #include <unistd.h>10 11 #define BUFSIZE 51212 #define NUM 513 14 /*15  * 這三個函數是我自定義的,功能就是利用strerror打印errno的信息,并且退出16  */17 void err_exit(char *fmt,...);18 int err_dump(char *fmt,...);19 int err_ret(char *fmt,...);20 21 int alrm_count = 0;    //對發送的alrm信號進行計數22 /*23  *  本函數用來處理SIGALRM信號24  */25 void sig_alrm(int signo)26 {27     alrm_count++;28     PRintf("In signal SIGALRM handler/n");29     if(SIG_ERR == signal(SIGALRM,sig_alrm))30         err_exit("[signal]: ");31     if(alrm_count < NUM) {32         alarm(1);33         pause();34     }35 }36 37 int main(int argc,char *argv[])38 {39     if(SIG_ERR == signal(SIGALRM,sig_alrm))40         err_exit("[signal]: ");41 42     /*alarm函數的功能就是在1s之后向本進程發送一個SIGALRM信號*/43     alarm(1);44     pause();45 46     return 0;47 }

  這個程序的29~30行就是在信號的處理函數中重新設置對SIGALRM的處理函數,下次產生SIGALRM這個信號的時候,繼續來調用這個處理函數。程序的運行結果如下:

  

  如果沒有29~30行那兩行的內容,程序的運行結果就會變成下面這樣:

  

  第一次接受到SIGALRM信號,程序會調用我們自定義的sig_alrm信號處理函數,但是第二次接受到SIGALRM信號的時候,程序就會調用系統默認的SIGALRM的信號處理函數了,此時就會打印出Alarm clock信息。

  2. SIGCHLD信號(SIGCLD)

    在linux下面,這兩個信號是等價的,所以就放在一起來討論。首先先把代碼貼上來:

 1 #include <errno.h> 2 #include <signal.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <stdarg.h> 6 #include <stdio.h> 7 #include <sys/types.h> 8 #include <sys/wait.h> 9 #include <unistd.h>10 11 #define BUFSIZE 51212 #define NUM 213 14 void err_exit(char *fmt,...);15 int err_dump(char *fmt,...);16 int err_ret(char *fmt,...);17 18 void sig_chld(int signo);19 20 int main(int argc,char *argv[])21 {22     pid_t pid;23 24     if(SIG_ERR == signal(SIGCHLD,sig_chld))25         perror("[signal]: ");26 27     for(int loop=0;loop<NUM;loop++) {28         if(-1 == (pid=fork())) {29             err_exit("[fork]:");30         } else if(0 == pid) {31             printf("I'm the No.%d Child %d/n",loop+1,getpid());32             return 0;33         } else {34             pause();35         }36     }37 38     return 0;39 }40 41 void sig_chld(int signo)42 {43     int status;44     pid_t cpid;45 46     /* printf("A child process terminated!/n"); */47     if(-1 == (cpid=wait(&status)))48         err_exit("[wait]: ");49     else50         printf("Process %d terminated!/n",cpid);51 52     if(SIG_ERR == signal(SIGCHLD,sig_chld))53         perror("[signal]: ");54 }

  這段代碼的作用就是父進程創建一個子進程,然后暫停,等待子進程結束發送SIGCHLD信號過來,在SIGCHLD信號的信號處理函數中,將子進程回收,并且打印出回收的子進程進程id。執行完這些步驟之后,再來繼續這個過程,直到循環了NUM次。

  這個程序的運行結果如下所示:

  

  這里可以看到,兩個子進程結束時發送的SIGCHLD信號都被接受到了,并且兩個子進程都被回收了。

  如果我去掉了在信號處理函數中的signal函數(52~53行),那么程序的運行結果就會如下圖所示:

  

  主函數卡死了,此時我用top命令來查看這進程信息,發現第二個子進程變成了僵尸進程,如下圖所示:

  

  此時SIGCHLD信號處理函數,變成了默認的忽略(SIG_IGN),接受到了SIGCHLD信號就不會調用函數了,而pause函數的說明則是這樣的:

  

  pause函數只有遇到讓主進程終止的信號,或者是產生信號處理函數調用的函數才會停止睡眠。而在上面的程序中,第二次的時候SIGCHLD信號由于采用的系統默認的配置SIG_IGN,此時不會產生信號處理函數的調用,所以主進程就繼續暫停。

  信號處理程序不會被重置的信號:

  目前我只發現了兩個,就是兩個用戶自定義的函數,SIG_USR1和SIG_USR2,具體可以參看下面這段代碼:

 1 #include<errno.h> 2 #include<signal.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #include<stdarg.h> 6 #include<stdio.h> 7 #include<unistd.h> 8  9 #define BUFSIZE 51210 11 /*12  * 這三個函數是我自定義的,功能就是利用strerror打印errno的信息,并且退出13  */14 void err_exit(char *fmt,...);15 void err_dump(char *fmt,...);16 int err_ret(char *fmt,...);17 18 void sig_handler(int signo)19 {20     if(signo == SIGUSR1)21       printf("Catch the SIGUSR1 [%d]/n",signo);22     else if(signo == SIGUSR2)23       printf("Catch the SIGUSR2 [%d]/n",signo);24     else25       err_dump("Catch the signal %d/n",signo);26 }27 int main(int argc,char *argv[])28 {29     if(SIG_ERR == signal(SIGUSR1,sig_handler))30       err_exit("[signal]1: ");31     if(SIG_ERR == signal(SIGUSR2,sig_handler))32       err_exit("[signal]2: ");33 34     for(;;)35       pause();36 37     return 0;38 }

  這個程序就是一直等待信號發送過來,并且會對SIGUSR1和SIGUSR2進行處理,其他信號則會執行系統默認的處理情況。運行的結果如下圖:

  程序開始后,我通過另一個終端給這個程序發送信號,如下圖所示:

  

  而程序運行的界面如下圖所示:

  

  從這里可以看出,我們只對SIGUSR這兩個函數設置了一次信號處理函數,但是它們的處理方式就不會被重置,發送多次SIGUSR信號都是同一種處理方式。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 芒康县| 桂林市| 莲花县| 陵川县| 莱芜市| 承德县| 玉田县| 武清区| 曲阳县| 南岸区| 东辽县| 茌平县| 绵竹市| 始兴县| 承德市| 张家界市| 理塘县| 会昌县| 都匀市| 合作市| 冷水江市| 绥棱县| 客服| 丽水市| 丹寨县| 大邑县| 库车县| 浦江县| 花垣县| 鄂伦春自治旗| 沛县| 澄江县| 蕉岭县| 博兴县| 和林格尔县| 青海省| 吉安市| 肥城市| 余庆县| 犍为县| 桦南县|