轉自 https://www.cnblogs.com/gaorong/p/6430905.htmlhtml
在linux下有不少信號,按可靠性分爲可靠信號和非可靠信號,按時間分爲實時信號和非實時信號,linux進程也有三種方式來處理收到的信號:linux
(1)忽略信號,即對信號不作任何處理,其中,有兩個信號不能忽略:SIGKILL及SIGSTOP;shell
(2)捕捉信號。定義信號處理函數,當信號發生時,執行相應的處理函數;apache
(3)執行缺省操做,Linux對每種信號都規定了默認操做。編程
Linux進程對實時信號的缺省反應是進程終止。可是對於高性能服務器編程來講,這是致命的缺陷,對於這類服務器須要保證在收到各類信號後仍然能夠可靠運行,因此咱們須要在理解各類信號的原因和正確的處理方式。本文將筆者常常碰到的一些信號進行整理,結合本身的使用經驗簡要分析。服務器
SIGHUP和控制檯操做有關,當控制檯被關閉時系統會向擁有控制檯sessionID的全部進程發送HUP信號,默認HUP信號的action是 exit,若是遠程登錄啓動某個服務進程並在程序運行時關閉鏈接的話會致使服務進程退出,因此通常服務進程都會用nohup工具啓動(該命令就是讓忽略該信號)或寫成一個 daemon(利用setsid進行)。網絡
如下五組能夠放在一塊類比session
SIGINT 終止進程,一般咱們的Ctrl+C就發送的這個消息。app
SIGQUIT 和SIGINT相似, 但由QUIT字符(一般是Ctrl- \ )來控制. 進程收到該消息退出時會產生core文件。tcp
SIGKILL 消息編號爲9,咱們常常用kill -9來殺死進程發送的就是這個消息,程序收到這個消息當即終止,這個消息不能被捕獲,封鎖或這忽略,因此是殺死進程的終極武器。
SIGTERM 是不帶參數時kill默認發送的信號,默認是殺死進程。
1.SIGINT SIGTERM區別
前者與字符ctrl+c關聯,後者沒有任何控制字符關聯。
前者只能結束前臺進程,後者則不是。
2.SIGTERM SIGKILL的區別
前者能夠被阻塞、處理和忽略,可是後者不能夠。
KILL命令的默認不帶參數發送的信號就是SIGTERM.讓程序有好的退出。
SIGTERM比較友好,進程能捕捉這個信號,根據您的須要來關閉程序。在某些狀況下,假如進程正在進行做業並且不能中斷,那麼進程能夠忽略這個SIGTERM信號。
由於SIGTERM能夠被阻塞,因此有的進程不能被結束時,須要用kill發送SIGKILL。即:kill-9 進程號。
SIGSTOP 中止進程的執行,同SIGKILL同樣不能夠被應用程序所處理,注意它和terminate以及interrupt的區別:該進程還未結束, 只是暫停執行.由 Ctrl+Z 控制,用戶可使用使用fg/bg操做恢復執行前臺或後臺的進程。fg命令在前臺恢復執行被掛起的進程,此時可使用ctrl-z再次掛起該進程,bg命令在後臺恢復執行被掛起的進程,而此時將沒法使用ctrl-z再次掛起該進程。
SIGCONT 當SIGSTOP發送到一個進程時,一般的行爲是暫停該進程的當前狀態。若是發送SIGCONT信號,該進程將僅恢復執行。除了其餘目的,SIGSTOP和SIGCONT用於Unix shell中的做業控制,沒法捕獲或忽略SIGCONT信號。
SIGPIPE 這個是向一個沒有讀進程的管道寫數據產生的錯誤,這種解釋過於官方。在網絡編程中這個信號發生在若是客戶端已經關閉了套接字, 而服務器調用了一次write,服務器就會收到一個RST segment,若是服務器再次調用write,這個時候就會產生SIGPIPE信號,系統默認的處理方式是關掉這個進程, 可是對於一個高可用的服務器程序來講,須要手動處理這個信號,因此你會看到許多服務器程序代碼會在前面顯式加上signal (SIGPIPE, SIG_IGN)來忽略這個信號。
SIGCHILD 這個一樣是高性能服務器須要關注的信號,若是服務器採用fork產生的子進程推出後要調用wait進行資源回收,防止殭屍進程的產生,可是若是程序對子進程退出後的狀態不感興趣的話能夠調用signal(SIGCHLD,SIG_IGN); 交給系統init去回收。子進程也不會產生殭屍進程了。
SIGSEGV 就是SegmentFault 試圖訪問未分配給本身的內存, 或試圖往沒有寫權限的內存地址寫數據,官方舉得三個例子是:
- buffer overflow --- usually caused by a pointer reference out of range. 野指針
- stack overflow --- please keep in mind that the default stack size is 8192K. 棧溢出
- illegal file access --- file operations are forbidden on our judge system. 非法文件訪問
SIGBUS 指針所對應的地址是有效地址,但總線不能正常使用該指針。一般是未對齊的數據訪問所致。試圖訪問一塊無文件內容對應的內存區域,好比超過文件尾的內存區域,或者之前有文件內容對應,如今爲另外一進程截斷過的內存區域。apache爆出的一個bug就是mmap調用的時候文件發生改變就會爆出這個錯誤,具體參考這篇精彩的博客是 : 由mmap引起的SIGBUS
關於上面兩個信號,《UNP》卷二中對於共享內存mmap引起這兩個錯誤的緣由用一張圖描述:
SIGBUS意味着咱們是在內存映射區內訪問,可是已超出了底層支撐對象的大小。SIGSEGV則意味着我i們在內存映射區之外訪問。
SIGURG I/O緊急信號,也就是tcp傳輸帶外數據時使用,可是tcp手冊 RFC6093中已經不建議使用緊急指針了,因此這個信號也就沒什麼用了。
SIGIO 當描述符上能夠進行I/O時產生這個信號,這時五大IO模型中信號驅動IO模型的實現信號。
SIGALRM 時鐘定時信號, 計算的是實際的時間或時鐘時間.alarm函數使用該信號.
以上就是編程中常見到的信號,也是最引人關注的信號,至於其餘信號,之後想起再寫吧。
2018.6.14 append:
https://www.linuxjournal.com/article/10815 shell 捕獲信號