【linux】signal信號

1、什么是信號
說到信號首先想到的是信號交通燈,“紅燈停,綠燈行,黃燈閃閃慢慢行”。這就是信號燈在交通中起的作用。在十字路口,常見的一個現(xiàn)象:當(dāng)為紅燈時,汽車停止形式,等待行人過馬路。從這個現(xiàn)象中,可以類比系統(tǒng)中的進(jìn)程中斷:
紅燈代表一種信號
汽車行駛代表進(jìn)程
行人過馬路代表信號觸發(fā)的事件

紅燈信號使汽車停止行駛,表示信號可以中斷進(jìn)程;
汽車停止行使后,行人可以過馬路,表示信號中斷進(jìn)程后可以觸發(fā)另一個事件;
紅燈變綠燈,行人過馬路結(jié)束,汽車可以繼續(xù)行駛。表示信號觸發(fā)的事件結(jié)束之后,進(jìn)程可以繼續(xù)執(zhí)行。
信號中斷大概如下圖:

系統(tǒng)中的信號載體都有一個名字,以“SIG”開頭,每個信號都有對應(yīng)的編號。
“信號是軟件中斷”[1]。
不存在編號為0的信號。
2、Linux系統(tǒng)上有哪些信號
執(zhí)行命令man 7 signal或者kill -l查看


說明:
SIGHUP - 1: 連接斷開。
SIGINT - 2:中斷信號,例如鍵盤按下:CTRL + C。
SIGQUIT - 3:退出信號,例如鍵盤按下: CTRL + \??梢赃M(jìn)去python解釋器,按下ctrl+\就會退出Python解釋器。
SIGILL - 4:非法(硬件)指令
SIGTRAP - 5: 指示一個實現(xiàn)定義的硬件故障。執(zhí)行斷點指令時,常用此信號將控制轉(zhuǎn)移至調(diào)試程序。(斷點調(diào)試用?)
SIGABRT - 6: 夭折信號,進(jìn)程調(diào)用abort函數(shù)時產(chǎn)生這種信號,進(jìn)程異常終止。
SIGBUS - 7: 內(nèi)存故障,產(chǎn)生此種信號。
SIGFPE - 8: 表示一個算術(shù)運算異常,如除以0、浮點溢出等。
SIGKILL - 9: 終止信號,例如:kill -9 xxpid,用于進(jìn)程的立即終止,不能被忽略或阻止,進(jìn)程與其線程一起終止,適用于無響應(yīng)的進(jìn)程。暴力~
SIGUSR1 - 10: 用戶定義的信號,可用于應(yīng)用程序。
SIGSEGV - 11: 硬件異常產(chǎn)生的信號,比如除數(shù)為0、無效的內(nèi)存引用等。
SIGUSR2 - 12: 用戶定義的信號,可用于應(yīng)用程序。
SIGPIPE - 13: 在管道的讀進(jìn)程已終止后,一個進(jìn)程寫此管道,會產(chǎn)生該信號。店已打烊,請勿來訪~
SIGALRM - 14: 鬧鐘信號,由alarm函數(shù)設(shè)置的定時器超時后產(chǎn)生此信號。
SIGTERM - 15: 終止信號。軟終止,kill命令默認(rèn)發(fā)送SIGTERM信號。該信號讓程序有機(jī)會在退出之前做好清理工作,優(yōu)雅地終止。和kill -9相比,SIGTERM不會殺死子進(jìn)程。
SIGSTKFLT - 16: 僅由Linux定義,它出現(xiàn)在Linux的早期版本,企圖用于數(shù)據(jù)協(xié)處理器的棧故障。該信號并非由內(nèi)核產(chǎn)生,但仍保留以向后兼容。
SIGCHLD - 17: 子進(jìn)程狀態(tài)改變。當(dāng)一個進(jìn)程終止或停止時,SIGCHLD信號被送給其父進(jìn)程。需要父進(jìn)程去捕捉,因為SIGCHLD信號默認(rèn)是忽略的。
SIGCOUT - 18: 使暫停進(jìn)程繼續(xù)。系統(tǒng)會根據(jù)進(jìn)程狀態(tài)判定默認(rèn)動作,如果接收到該信號的進(jìn)程是停止?fàn)顟B(tài),默認(rèn)動作是繼續(xù);否則默認(rèn)動作是忽略此信號。
SIGSTOP - 19: 停止
SIGTSTP - 20: 停止終端輸入。例如:鍵盤按下CTRL + Z。
SIGTTIN - 21: 當(dāng)一個后臺進(jìn)程組進(jìn)程試圖讀其控制終端時,終端驅(qū)動程序產(chǎn)生此信號。
SIGTTOU - 22:?當(dāng)一個后臺進(jìn)程組進(jìn)程試圖寫其控制終端時,終端驅(qū)動程序產(chǎn)生此信號。
SIGURG - 23: 在網(wǎng)絡(luò)連接上傳來帶外的數(shù)據(jù)。通知進(jìn)程已經(jīng)發(fā)生了一個緊急情況。
SIGXCPU - 24: 超過軟CPU時間(疑惑:軟CPU時間指的是發(fā)生中斷CPU做指定請求處理消耗的時間?)限制,則產(chǎn)生此信號。
SIGXFSZ - 25: 如果進(jìn)程超過了其軟文件長度限制,則產(chǎn)生此信號。
SIGVTALRM - 26: 當(dāng)一個由setitimer(2)函數(shù)設(shè)置的虛擬間隔時間已經(jīng)超時時,產(chǎn)生此信號。
SIGPROF - 27: 當(dāng)setitimer(2)函數(shù)設(shè)置的梗概統(tǒng)計間隔定時器已經(jīng)超時時產(chǎn)生此信號。
SIGWINCH - 28: 內(nèi)核維持與每個終端或偽終端相關(guān)聯(lián)窗口的大小。如果ioctl更改了窗口大小,內(nèi)核會將SIGWINCH信號發(fā)送給前臺進(jìn)程組。
SIGIO - 29: 此信號指示一個異步I/O事件。
SIGPWR?- 30: 主要用于不間斷電源(UPS)的系統(tǒng)。如果電源失效,則UPS啟動,系統(tǒng)如果能依靠蓄電池繼續(xù)運行,無需做任何處理;如果蓄電池也不能使系統(tǒng)繼續(xù)運行,此時就會發(fā)送SIGPWR信號給init進(jìn)程,然后由init進(jìn)程處理停機(jī)操作。
SIGSYS - 31: 當(dāng)進(jìn)程執(zhí)行了一條機(jī)器指令,但是參數(shù)卻是無效的,會產(chǎn)生該信號。
SIGRTMIN - 32: 編號32之后的信號都是自定義信號,還未接觸,以后用到了在這補(bǔ)充~
3、信號的處理
3.1 忽略信號
大多數(shù)信號都可以執(zhí)行使用忽略來處理,但是SIGKILL和SIGSTOP不能被忽略。
3.2 捕捉信號
通知內(nèi)核在信號發(fā)生時,調(diào)用一個用戶函數(shù)。但是SIGKILL和SIGSTOP信號不能捕捉。
3.3 執(zhí)行系統(tǒng)默認(rèn)動作
大多數(shù)信號的系統(tǒng)默認(rèn)動作是終止該進(jìn)程。
函數(shù)signal()
參數(shù)含義:
signo: 信號名
func: 可以是SIG_IGN、SIG_DEL、函數(shù)地址
SIG_IGN: ignor,忽略此信號。
SIG_DEL: default,接到此信號之后的動作是系統(tǒng)默認(rèn)動作。
函數(shù)地址: 信號發(fā)生時,調(diào)用指定的函數(shù),這種處理方式叫做捕捉該信號,調(diào)用的函數(shù)叫做信號處理函數(shù)或信號捕捉函數(shù)。
4、注意
# 在類UNIX系統(tǒng)中,kill命令或kill函數(shù)被看作殺死是不恰當(dāng)?shù)?。kill只是將一個信號發(fā)送給一個進(jìn)程或進(jìn)程組。該信號是否終止進(jìn)程取決于該信號的類型,以及進(jìn)程是否安排了捕捉該信號。
比如:kill -USR1 xxxpid?是向xxxpid進(jìn)程發(fā)送SIGUSR1信號。
5、參考資料
[1] W.Richard Stevens/Stephen A.rago.UNIX環(huán)境高級編程第3版[M].北京:人民郵電出版社,2014:249.