Linux

為什麼有時需要通過 kill -9 停止程序

  • January 7, 2019

我們在 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 處理程序

引用自:https://unix.stackexchange.com/questions/493019