[英]Java - kill external process with TimerTask
我實現了一個方法,其中使用 processBuilder 調用外部程序。 如果外部進程花費的時間超過 5 秒(出於測試原因),我想停止該任務。
當我使用 process.exec() 時,實現工作正常。 但不是 processBuilder.start()
我已經閱讀了一些帖子,但它似乎不起作用,因為我無法弄清楚我錯過了什么。
方法:
ProcessBuilder processBuilder = new ProcessBuilder("/.../test.bat -a -b -c").redirectErrorStream(true);
Process process = processBuilder.start();
Timer t = new Timer();
TimerTask killer = new TimeoutProcessKiller(process);
t.schedule(killer, 5 * 1000);
BufferedReader lineReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
lineReader.lines().forEach(str -> LOGGER.log(Level.INFO, str));
int lExitCode = process.waitFor();
if (lExitCode == 0) {
LOGGER.log(Level.INFO, "Process finished successful.");
} else {
LOGGER.log(Level.INFO, "Process finished not successful.");
}
killer.cancel();
超時進程殺手
public class TimeoutProcessKiller extends TimerTask {
private Process p;
public TimeoutProcessKiller(Process p) {
this.p = p;
}
public void run() {
p.destroy();
}
}
謝謝你的任何建議。
您的問題很可能是因為您的批處理腳本已經啟動了子進程,這些子進程在您的任務破壞了父進程后仍在運行。 更改TimeoutProcessKiller.run()
方法以打印出descendants
(子進程及其所有子進程),然后也將其殺死。
以下將打印每個嘗試殺死它們的PID:
public void run() {
System.out.println("destroying "+p);
p.destroy();
System.out.println("destroying descendants");
p.descendants().peek(System.out::println).forEach(ProcessHandle::destroy);
System.out.println("destroyed "+p);
}
您從Runtime.exec()
到ProcessBuilder
所做的更改不是原因 - 因為Runtime.exec()
是對ProcessBuilder
的調用。 如果您不使用 STDOUT stream ,后代的問題就會消失(這不是一件明智的事情,因為這會凍結進程),所以您很可能在從Runtime.exec()
交換之后添加了BufferedReader lineReader...
?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.