程序kill -9與kill -15的區別,以及回調函數的作用

在Linux/unix下,中止一個Java進程有兩種方式,一種是kill -9 pid,一種是kill -15 pill(默認)。

兩種方式的區別是:

SIGNKILL(9) 的效果是立即殺死進程. 該信號不能被阻塞, 處理和忽略。
SIGNTERM(15) 的效果是正常退出進程,退出前可以被阻塞或回調處理。並且它是Linux缺省的程序中斷信號。

---》標準中斷信號
在Linux信號機制中,存在多種進程中斷信號(Linux信號列表)。其中比較典型的有 SIGNKILL(9) 和 SIGNTERM(15).

由此可見,SIGNTERM(15) 纔是理論上標準的kill進程信號。
那使用 SIGNKILL(9) 又有什麼錯呢?

SIGNKILL(9) 帶來的問題
看下面一段程序:

public class ShutdownHookTest {

 private static final void shutdownCallback() {
  System.out.println("Shutdown callback is invoked.");
 }

 public static void main(String[] args) throws InterruptedException {
  Runtime.getRuntime().addShutdownHook(new Thread() {

   @Override
   public void run() {
    shutdownCallback();
   }

  });
  Thread.sleep(10000);
 }

}
在上面這段程序中,我使用Runtime爲當前java進程添加了一個ShutdownHook,它的作用是在java正常退出時,執行shutdownCallback()這個回調方法。
此時,如果你試驗過在java進程未自動退出前,執行 kill -9 pid,即發送 SIGNKILL 信號,會發現這個回調接口是不會被執行的。這是SIGNKILL信號起的作用。

對於我這個簡單的測試用例來說,不被執行也無大礙。但是,如果你的真實系統中有需要在java進程退出後,釋放某些資源。
而這個釋放動作,因爲SIGNKILL被忽略了,那就可能造成一些問題。

所以,推薦大家使用標準的kill進程方式,即 kill -15 pid。

---》》此外,如果想在程序被kill之前執行某些操作,就可以用到這個例子中的Runtime.getRuntime().addShutdownHook函數了,它是一個回調函數,在被kill之前會執行這個函數裏面的內容。

 


原文鏈接:https://blog.csdn.net/ungoneless/article/details/53191719

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