Linux
為什麼有時需要通過 kill -9 停止程序
我們在 hadoop 集群中有 kafka 機器
停止 kafka 程序的腳本執行以下操作
殺死PID
但我們注意到停止 kafka 的腳本並沒有真正殺死程序
因此我們通過以下方式(手動)殺死了它:
殺死 -9 PID
所以 - 在這種情況下,程序堅持被 -9 殺死(而不是僅僅殺死 pid )
腳本中的範例
function kafkaKill { local localPID=$1 kill $localPID || return 1 for ((i=0; i<MAX_WAIT_TIME; i++)); do kafkaIsRunning $localPID if [ $? -eq 0 ]; then return 0; fi sleep 1 done kill -s KILL $localPID || return 1 for ((i=0; i<MAX_WAIT_TIME; i++)); do kafkaIsRunning $localPID if [ $? -eq 0 ]; then return 0; fi sleep 1 done return 1 }
預設情況下,向程序發送標準終止會發送(根據維基百科)SIGTERM。這樣做是通知程序它應該關閉。這是處理這個過程的好方法,它是這樣的:
為 SIGTERM 處理寄存器信號交易
你想殺死程序
你通過 kill 發送 SIGTERM
呼叫信號處理程序,這是程序執行的機會
- 關閉它打開的文件
- 寫出任何緩衝區
- 關閉所有子執行緒
發送強制程序退出的 SIGTERM 沒有任何意義。它可以完全忽略它,也可以隨心所欲地行事。
Kill -9 發送 SIGKILL。您不允許為 SIGKILL 註冊處理程序,這意味著呼叫預設值(我相信核心空間 - 有人在這裡糾正我)。在這種情況下,您沒有機會執行上述操作,您的程序會立即從可執行程序列表中刪除,並且它的記憶體和所有內容都將被銷毀。如果您正在寫入文件,這顯然會導致問題。
有些程序在關閉之前會接收多個 SIGTERM 信號 - 你試過嗎?該過程還可能記錄您可以發送哪些信號以徹底關閉它。
處於不良狀態的程序可能沒有機會訪問信號處理程序,即使它已經註冊了一個。有些地方無法接收到信號(您處於中斷狀態,或者已經在處理另一個信號,還有一些我目前無法確定的其他信號)。如果您的程序卡在這些點之一(無論出於何種原因),則 SIGTERM 處理程序將永遠不會執行,無論您發送多少次。這裡唯一的解決方案是 SIGKILL,但是我什至見過忽略該信號的情況,在這種情況下需要重新啟動系統。
實際答案
要回答您的問題-在哪些情況下會忽略殺死並堅持用-9殺死:
- 該程序已經註冊了一個 SIGTERM 處理程序,該處理程序專門不會終止該程序(注意 - 預設 SIGTERM 將終止該程序)
- 程序卡在信號阻塞狀態,無法執行 SIGTERM 處理程序