1、什麼是信號
一、 信號就是軟件中斷,不少的程序都須要處理信號。信號提供了一種處理異步事件的機制。
例如:當用戶在終端下運行一個程序時,用戶在鍵盤鍵入一箇中斷鍵(CTRL+C),則會經過信號機制終止一個正在運行的程序。
二、每個信號都有本身獨特的名字。這些名字都是以SIG開頭的。例如中斷信號SIGINT.在linux下輸入shell命令kill -l能夠看到linux所支持的全部的信號名稱以及信號的編號。其中1號到32號(32號信號用戶是不能使用的)信號都是繼承UNUX系統的信號。其他的 是linux系統根據POSIX標註定義的信號。
三、在編寫信號程序時,必須加上頭文件<signal.h>。事實上,信號的定義的定義在另外的一個頭文件中,可是該頭文件又包含在<signal.h>中。
你們能夠查看頭文件/usr/include/signal.h 發現裏邊有一句include <bits/signum.h>,而後再查看頭文件/usr/include/bits/signum.h 你們會發現信號的定義都在這裏邊.
2、信號產生的方式
一、用戶按鍵,如用戶按下了CTRL+C組合鍵
二、硬件異常,如除數爲0,無效內存引用
三、進程調用kill函數將信號發送給一個進程或者進程組,限制條件是:接受信號進程和發送信號進程的全部者必須相同。或者發送信號的進程的全部者是超級用戶
四、調用命令kill,實際上此命令是kill函數的接口
五、檢測到某種軟件條件已經發生。例如 SIGPIPE(管道的讀進程已經終止後,另外一個進程寫此管道時產生)
當產生信號時,內核一般會在進程表中設置一個某種形式的標誌,這就是所謂的向進程發送了一個信號。
3、進程的處理
一、捕捉信號,能夠指定信號的處理函數,當捕捉的信號時自動執行此函數
二、忽略信號,除了SIGKILL和SIGSTOP,由於它們向超級用戶提供了使進程終止或中止的方法。另外忽略了由某些硬件異常產生的信號(如無效內存引用),則進程運行的行爲是不可預測的。
三、按照系統默認的方式處理,大部分信號的默認處理方式是終止進程 linux
四.linux下的信號 shell
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
五.簡單實例 異步
1.單信號處理 函數
#include"stdio.h"
#include"signal.h"
void SignalHandler(int iSignNum)
{
printf("capture signal number:%d\n",iSignNum);
}
int main()
{ // 程序運行Ctrl+c將不能終止,由於「Ctrl+c」產生的信號SIGINT
//將交給已經註冊的自定義函數處理,「Ctrl+\」終止是由於它產生的SIGQUIT還沒有在程序中註冊
signal(SIGINT,SignalHandler);
while(1)
sleep(1);
return 0;
} 繼承
2.多信號處理 接口
#include"stdio.h" #include"signal.h" #include"sys/types.h" #include"unistd.h" void SigRoutine(int iSignNum) { switch(iSignNum) { case 1: printf("capture SIGHUP signal, signal number is %d\n",iSignNum); break; case 2: printf("capture SIGINT signal, signal number is %d\n",iSignNum); break; case 3: printf("capture SIGINT signal, signal number is %d\n",iSignNum); break; } } int main() { printf("process ID is %d\n",getpid()); if(signal(SIGHUP,SigRoutine) == SIG_ERR) { printf("coundn't register signal handler for SIGHUP"); } if(signal(SIGINT,SigRoutine) == SIG_ERR) { printf("coundn't register signal handler for SIGINT"); } if(signal(SIGQUIT,SigRoutine) == SIG_ERR) { printf("coundn't register signal handler for SIGQUIT"); } while(1) sleep(1); return 0; } 3.alarm #include"stdio.h" #include"signal.h" #include"sys/types.h" #include"unistd.h" void Handler() { printf("signal handler ..\n"); } int main() { int i; signal(SIGALRM,Handler); // alarm專門爲SIGALRM信號而設,使系統在必定時間後發送信號 alarm(5); for(i=1;i<=10;i++) { sleep(1); printf("sleep %ds\n",i); } return 0; } 4.pause #include"stdio.h" #include"signal.h" #include"sys/types.h" #include"unistd.h" void SigHandler(int iSignNum) { printf("signal:%d\n",iSignNum); } int main() { signal(SIGALRM,SigHandler); alarm(5); printf("before pause \n"); pause(); printf("after pause \n"); return 0; }