2015-08-26 26 views
1

我的Intel MPI版本是在RHEL機器上安裝的impi/5.0.2.044/intel64版本。Intel MPI mpirun不會使用java Process.destroy()終止

我用java使用下面的代碼來調用MPI程序:

ProcessBuilder builder = new ProcessBuilder(); 
builder.command("mpirun ./myProgram"); 
builder.redirectError(Redirect.to(new File("stderr"))); 
builder.redirectOutput(Redirect.to(new File("stdout"))); 
Process p = null; 
try { 
    p = builder.start(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
// Process has started here 
p.destroy(); 
try { 
    // i = 143 
    int i = p.exitValue(); 
} catch(IllegalThreadStateException e){ 
} 

exitValue()沒有拋出異常被稱爲後,也ps aux仍然顯示了一堆./myProgram和程序還在寫結果文件就好像它沒有被殺死一樣,只有在它完成了所有的計算後才終止。

目前,我發現成功終止./myProgram的唯一方法是在控制檯的java程序中使用Ctrl+C終止java。

我的意圖是立即停止計算並讓java程序計劃一些其他計算。是否有任何步驟來強制所有mpi實例終止,或者至少保證在一定的時間內(例如30秒或1分鐘的輪詢)終止?

回答

2

問題是,destroy的JDK實現發送SIGTERM,這會很難關閉mpirun。 有關JDK源代碼,請參閱here

您需要發送SIGINT才能讓MPI有機會正常關機。

E.g. Runtime.getRuntime().exec("kill -9 <pid>");

您可以通過調用mpirun--report-pid來獲得PID。 (閱讀手冊頁)

編輯

您也可以使用反射來計算你的類UNIX操作系統(從here被盜)下啓動的過程中出了PID。正如我們在談論殺戮和信號,這不應該是一個限制。

if(process.getClass().getName().equals("java.lang.UNIXProcess")) { 
    /* get the PID on unix/linux systems */ 
    try { 
    Field f = process.getClass().getDeclaredField("pid"); 
    f.setAccessible(true); 
    pid = f.getInt(p); 
    } catch (Throwable e) { 
    } 
} 
+0

現在我明白了問題所在。我殺死了MPI啓動器,但不是程序。然而,我的'mpirun'版本不會響應'--report-pid'選項和'I_MPI_DEBUG'環境變量,所以我不知道如何獲得PID。 – kftse

+0

請參閱編輯以查找java的pid的通用方法。 – marc

+0

感謝您的反射代碼。我應該接受你的解決方案,因爲它通常是正確的。但是,英特爾MPI仍然詛咒不傳播我的信號。我嘗試了掛斷(1),中斷(2),終止(9)和終止(15),無論是否終止,或者使守護進程死掉而不終止MPI進程。 – kftse