我已經在網上搜索,而process.waitFor() never returns這個問題表明它的stdout或stderr沒有被讀取的進程通常是一個問題。Process.waitFor即使stdout和stderr被讀取也會掛起
我們使用ProcessBuilder
與redirectOutput
和redirectError
實現這一目標,我想我們應該是在安全方面,看看我們用它來執行過程如下方法:
public static void execute(String directory, long timeout, File out, File err, String... command) throws InterruptedException, IOException {
LOGGER.log(Level.INFO, String.format("executing command %s (%s)", Arrays.toString(command), timeout > 0 ? String.format("timeout = %,d[ms]", timeout) : "no timeout"));
ProcessBuilder builder = new ProcessBuilder();
builder.directory(new File(directory));
builder.command(command);
builder.redirectOutput(out);
if(out == err) {
builder.redirectErrorStream(true);
} else {
builder.redirectError(err);
}
long time = System.currentTimeMillis();
Process process = builder.start();
try {
LOGGER.log(Level.FINE, "waiting for process");
boolean exited = process.waitFor(timeout, TimeUnit.MILLISECONDS);
if(!exited) {
LOGGER.log(Level.WARNING, "timeout reached, trying to destroy ...");
exited = destroy(silent, process); // Helper method to destroy processes
}
long duration = System.currentTimeMillis() - time;
int exitValue = process.exitValue();
LOGGER.log(Level.INFO, "execution finished in " + duration + "[ms] => " + exitValue);
} catch (InterruptedException | Error | RuntimeException e) {
LOGGER.log(Level.SEVERE, "execution failed", e);
throw e;
}
}
然而,問題是,它掛起在process.waitFor(timeout, TimeUnit.MILLISECONDS)
調用,即使過程應該很容易在超時內完成。
測井輸出是
Oct 07, 2017 12:39:55 AM at.ProcessExecutor execute
INFO: executing command [java, -Xmx8G, -XX:+UseG1GC, -XX:+CrashOnOutOfMemoryError, -jar, MetricCalc.jar] (timeout = 14,400,000[ms])
Oct 07, 2017 12:39:55 AM at.ProcessExecutor execute
FINE: waiting for process
(認識到,沒有execution finished
線尚未寫入)
的err
文件讀取
... Things we write to std.err ...
Finished Metrics
和MetricCalc的主要方法如下所示
public static void main(String[] args) {
.... do some stuff ...
System.err.println("Finished Metrics");
}
這表明讀取工作正常,Java程序的最後一行已經執行並且進程應該終止。
任何人有一個想法,爲什麼進程不會終止/它仍然掛在Process.waitFor()
?
*「......並且該流程應該已經終止。」* - 假定子流程按照您的預期工作。檢查子進程是否實際終止;例如使用「ps -efl」或類似的。 –
@StephenC:我仍然可以使用'ps -efl | grep「java -Xmx8G」',表示它沒有終止。 然而,我不知道爲什麼這是這樣的情況,因爲MetricCalc的最後一行代碼(作爲進程運行的Java程序)已經執行... –
哦,它剛剛出現在我的腦海裏:可能是MetricCalc有一些非deamon線程正在運行,從而阻止應用程序終止...我將不得不測試這... –