2011-05-13 135 views
7

我有一個運行另一個(Python)程序的java程序作爲進程。程序終止時用`exec`終止進程

Process p = Runtime.getRuntime().exec("program.py", envp); 

如果java程序完成處理,Python過程也完成了。 finish命令發送一個信號給Python進程關閉它。

在正常情況下該過程被關閉是這樣的:

BufferedWriter output = new BufferedWriter(new OutputStreamWriter(p.getOutputStream())); 
output.write("@EOF\n"); 
output.flush(); 

然而,當Java程序崩潰,進程不會被關閉。由於崩潰,關閉命令不會發送。每次程序終止時是否可以自動終止進程?

+0

我其實對這個問題的答案其實也很感興趣。雖然我無法提供它,但您是否介意分享爲什麼Java程序崩潰? – Vinay

+1

爲了回答此問題,您需要提供更多信息。例如:您是否可以自由修改Java和Python程序中的一個或兩個的源代碼? –

+0

我不得不不同意Vinay(哈哈同名)。我現在正在查找它,但是我認爲只有在當前的Java Process ID正在運行時才運行該python Process的某些內容才能解決問題。不知道我是否在正確的道路上,但這個問題真的讓我感到不安。 – Vinay

回答

2

假設通過崩潰你意味着Java程序引發異常,那麼我會在發生這種情況時殺死Python進程。我還沒有看到你的代碼,但:

class Foo { 

    Process p; 

    private void doStuff() throws Exception { 
     p = Runtime.getRuntime().exec("program.py", envp); 
     // More code ... 
    } 

    private void startStuff() { 
     try { 
      doStuff(); 
     } catch (Exception e) { 
      p.destroy(); 
     } 
    } 

    public static void main(String[] args) { 
     Foo foo = new Foo(); 
     foo.startStuff(); 
    } 
} 

像這樣的東西應該只要是導致程序從doStuff()崩潰逃逸例外的工作。

即使您不希望程序在完成時以這種方式崩潰,我認爲這種方法要比將其封裝在shell腳本中更好,該腳本以某種方式終止了Python進程。在你的程序中處理它並不那麼複雜,在程序完成後保存代碼甚至可能是一個好主意,因爲你可能仍然有你不知道的錯誤。

+0

這不是一個完美的解決方案,但在我的情況下,這種模式已經足夠。 – czuk

3

嘿@czuk會一個ShutdownHook鉤有什麼用?這將處理以下情形

Java虛擬機在響應關閉以兩種事件:

  • 程序正常退出,當最後一個非守護線程退出時或退出(等價地,System.exit)方法被調用,或者

  • 響應於用戶中斷(例如鍵入^ C)或系統範圍事件(如用戶註銷或系統關閉)而終止虛擬機。

當系統意外崩潰時,這並不容易捕獲。

也許使用Thread.setDefaultUncaughtExceptionHandler方法?

+2

「關閉鉤子也應該快速完成他們的工作,當一個程序調用退出時,期望的是虛擬機會立即關閉並退出。當虛擬機因用戶註銷或系統關閉而終止時,底層操作系統可能只允許一段固定的時間關閉並退出,因此不宜嘗試任何用戶交互或在關閉掛鉤中執行長時間運行計算。「 殺死Python進程不需要很長時間。看起來像OP的完美解決方案(並扼殺我的興趣)。 :) – Vinay