Intel MPI mpirun не завершает работу с помощью Java Process.destroy()
Моя версия Intel MPI - impi/5.0.2.044/intel64, установленная на машине RHEL.
Я использую 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 мин опроса)?
1 ответ
Проблема в том, что реализация JDK destroy
посылает SIGTERM
, который выключается mpirun
жесткий. Смотрите здесь для соответствующего источника JDK.
Вам необходимо отправить SIGINT
чтобы дать MPI возможность корректно завершить работу.
Например Runtime.getRuntime().exec("kill -9 <pid>");
Вы можете получить PID, вызвав mpirun
с --report-pid
, (прочитайте справочную страницу)
редактировать
Вы также можете использовать отражение, чтобы выяснить PID процесса, который вы запустили под UNIX-подобной ОС (украдена отсюда). Поскольку мы говорим об убийстве и сигнале, это не должно быть ограничением.
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) {
}
}