kill命令與進程間的信號機制的討論

kill命令與進程間的信號機制的討論

本文實際上算是<深入理解計算機系統>第八章異常控制流中關於進程信號機制的一次小小的總結和書摘.只是剛好那kill命令作爲切入口而已.平時算是經常敲kill命令,主要有兩個,一個是隔三差五強制關閉進程,一個是給nginx重啓.剛好看書看到關於kill函數與內部信號的實際機制,本文算是一個回顧.

===

kill命令

關於kill命令,我們先來看看man怎麼說的:

kill 給指定進程發送指定信號. 如果沒有指定信號, 則發送 TERM 信號. TERM 信號會殺死不能俘獲該信號的進程. 對於其他進程, 可能需要使用 KILL (9) 信號,因爲該信號不能夠被俘獲.

其實按照他的描述,把kill命令,稱呼爲send signal會更爲合適,實際上是用於在給某個進程傳送信號(signal).

進程與信號機制

進程是一個執行中的程序的實例(換而言之一個程序可以有多個進程).一個進程具有一個獨立的邏輯控制流.在這組控制流進行中我們需要一組機制來實現控制流的轉移,進程與系統之間,進程在系統層面我們提供了異常(exception)來進行.而在更高層次的軟件層次上則提供了信號機制(signal).

信號本身是一組消息,他是系統用來通知進程發生了某一類事件.這些事件可以使是系統發生異常(例如除零)或者是來自硬件的終端(CTRL+C),也可以來自其他進程(因此信號也提供了一種進程間的通信機制).常見的信號如下圖.感興趣的朋友可以直接敲命令 man 7 signal

在這裏插入圖片描述

比如我們經常使用kill -s 9 pid ,這裏的9就是強制終止信號.SIGKILL.

信號處理機制

通常情況下發送信號有兩種原因.

  • 內核檢測到一個系統事件.
  • 使用kill函數,在命令上可以通過kill命令來調用kill函數.

一個進程可以給自己發送信號.

當目的進程接受到內核發送過來的信號後,他可以選擇忽略信號,停止自己,或者通過信號處理函數來處理信號.如果使用信號處理函數來處理,我們如下圖

在這裏插入圖片描述

信號的柱塞

信號提供了柱塞的機制.包含隱式柱塞和顯式柱塞.內核默認柱塞當前任何程序正在執行的進程處理函數的信號.也就是說某個信號正在被處理,此時一個新的相同類型信號到來後他被內核柱塞了,之後新的同類型信號會被忽略.顯式柱塞不在本文的討論過程中,他在編程中使用函數柱塞和關閉柱塞.要注意sigkill信號無法被柱塞和忽略.

kill命令的參數pid

很多文章提kill命令,都不會提到這個pid的不同,只會說pid是進程id.實際上如果你看kill函數的參數就可以看出端倪.
int kill(pid_t pid,int sig);
pid有幾種情況:

  • pid>0 將信號傳給進程識別碼爲pid 的進程。
  • pid=0 將信號傳給和目前進程相同進程組的所有進程(關於進程組可以看這篇文章)
  • pid=-1 將信號廣播傳送給系統內所有的進程
  • pid<0 將信號傳給進程組識別碼爲pid絕對值的所有進程

命令kill作爲kill函數的實現可以看出他也是一早pid參數設置,只不過當前進程被定位當前的termial.因此查看文檔我們可以看到pid的參數說明,實際和kill函數類似

  • n n>0是就是當前的進程id的曾經被髮送信號

-0 所有當前進程的進程組被髮送信號

-1 .將信號廣播傳送給系統內所有的進程id>1的進程.(不能是1.因爲1是linux的系統進程)

-n 在這種情況下, 發信號給屬於進程組 n 的進程如果給定一個負的參數, 那麼信號 必須 首先聲明,否則它會被當作信號發送出去

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章