0
我正在使用Java Executors.newWorkStealingPool();
並行運行多個命令。由於其中一些任務預計會超時,所以我爲它們添加了2秒的超時時間。進程不終止
ProcessBuilder pb = new ProcessBuilder(cmd.split(" "));
Process p = null;
StringBuilder result = new StringBuilder();
try {
p = pb.start();
p.waitFor(2000, TimeUnit.MILLISECONDS);
BufferedReader errreader =
new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader outreader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = outreader.readLine())!= null)
result.append(line + "\n");
while ((line = errreader.readLine())!= null)
result.append(line + "\n");
outreader.close();
errreader.close();
} catch (InterruptedException e) {
result.append("INTERRUPTED");
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
finally {
p.destroy();
}
....
return b; // b is boolean
提交任務看起來像這樣
List<ImmutablePair> curJobs = new ArrayList<ImmutablePair>();
for (int i = 0; i < allMutants.size(); i++) {
String mutant = allMutants.get(i);
t = executor.submit(new mutTask(mutant));
ImmutablePair pair = new ImmutablePair(mutant, t);
curJobs.add(pair);
}
最後。我在下面的循環中收集結果。
// data collection loop
for (int i = 0; i< curJobs.size(); i++) {
ImmutablePair p = curJobs.get(i);
String m= (String) p.getLeft();
System.out.println(m);
t = (Future<Boolean>) p.getRight();
try {
boolean res;
try {
res = t.get(2000L, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
res = true;
}
finally {
t.cancel(true);
}}
問題是,超時似乎並沒有終止程序中定義的某些命令或進程。幾分鐘後數據收集循環變得非常緩慢。 ps
的結果顯示了一些超出指定超時運行並保持CPU繁忙的作業。我的配置是CentOS上的JDK8。
所以輸出,從JavaDoc中,我們知道*「造成當前線程等待,如果必要的話,直到由該Process對象表示的子進程已經終止,或經過指定的等待時間。「*,這意味着此方法將在進程存在或指定時間過去時返回,這意味着進程可能仍在運行。接下來,您將讀取流程輸出的內容,這意味着如果流程仍然處於崩潰狀態,則它仍在處理輸出或阻塞......通常我使用子線程「Thread」來讀取輸入,當waitFor '返回,停止這些線程 – MadProgrammer
...然後銷燬進程 – MadProgrammer
謝謝。正如你注意到的那樣,問題是沒有檢查'p.waitFor(2000,TimeUnit.MILLISECONDS);'的輸出。 – Amin