更新時間:2020-12-25 17:36:03 來源:動力節點 瀏覽1216次
信號(Signals)是Unix、類Unix以及其他POSIX兼容的操作系統中進程間通訊的一種有限制的方式。Linux信號是Linux進程間通信機制中唯一的異步通信機制,用來提醒進程一個事件已經發生。當一個信號發送給一個進程,操作系統中斷了進程正常的控制流程,此時,任何非原子操作都將被中斷。如果進程定義了信號的處理函數,那么它將被執行,否則就執行默認的處理函數。
一般情況下,linux信號的來源可分為以下三種:
1.硬件方式:除數為零、無效的存儲訪問等硬件異常產生信號。這些事件通常由硬件(如:CPU)檢測到,并將其通知給Linux操作系統內核,然后內核生成相應的信號,并把信號發送給該事件發生時正在進行的程序。
2.軟件方式:用戶在終端下調用kill命令向進程發送任務信號、進程調用kill或sigqueue函數發送信號、當檢測到某種軟件條件已經具備時發出信號,如由alarm或settimer設置的定時器超時時將生成SIGALRM信號等多種情景均可產生信號。
3.鍵盤輸入:當用戶在終端上按下某鍵時,將產生信號。如按下組合鍵Ctrl+C將產生一個SIGINT信號,Ctrl+\產生一個SIGQUIT信號等。
我們可運行kill -l查看Linux支持的信號列表:
sl@Li:~/Works$ kill -l
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
可以看到Linux中系統一共支持64種信號,其中1到31號信號為普通信號(也程為不可靠信號),34到64為實時信號(可靠信號)。可靠信號與不可靠信號的區別:
這里的不可靠主要是不支持信號隊列,就是當多個信號發生在進程中的時候(收到信號的速度超過進程處理的速度的時候),這些沒來的及處理的信號就會被丟掉,僅僅留下一個信號。
可靠信號是多個信號發送到進程的時候(收到信號的速度超過進程處理信號的速度的時候),這些沒來的及處理的信號就會排入進程的隊列。等進程有機會來處理的時候,依次再處理,信號不丟失。
下面列出幾個常用的信號:
SIGHUP:
當用戶退出終端時,由該終端開啟的所有進程都退接收到這個信號,默認動作為終止進程。
SIGINT:
程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl+C)時發出,用于通知前臺進程組終止進程。
SIGQUIT:
和SIGINT類似, 但由QUIT字符(通常是Ctrl+\)來控制. 進程在因收到SIGQUIT退出時會產生core文件, 在這個意義上類似于一個程序錯誤信號。
SIGKILL:
用來立即結束程序的運行. 本信號不能被阻塞、處理和忽略。
SIGTERM:
程序結束(terminate)信號, 與SIGKILL不同的是該信號可以被阻塞和處理。通常用來要求程序自己正常退出。
SIGSTOP:
停止(stopped)進程的執行. 注意它和terminate以及interrupt的區別:該進程還未結束, 只是暫停執行. 本信號不能被阻塞, 處理或忽略。
代碼示例:
下面的代碼收到程序退出信號后會執行用戶定義的信號處理函數來替代系統默認的處理程序。
#include<stdlib.h>
#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
void sig_handle(int sig) {
printf("received signal: %d, quit.\n", sig);
exit(0);
}
int main () {
signal(SIGINT, sig_handle);
signal(SIGKILL, sig_handle);
signal(SIGSEGV, sig_handle);
signal(SIGTERM, sig_handle);
int i = 0;
while (1) {
printf("%d\n", ++i);
sleep(2);
}
printf("main quit.");
return 0;
}
運行結果:
received signal: 15, quit.
實際上,Linux信號可以看作是異步通知,通知接收信號的進程有哪些事情發生了,也可以簡單理解為信號是某種形式上的軟中斷。想要深入了解Linux信號的運行機制,可以參考本站的Linux教程中給出的資料,結合自己在Linux系統上的實踐操作得出自己的結論。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習