【问题标题】:Executing process with ProcessBuilder causes hang on waitFor使用 ProcessBuilder 执行进程会导致 waitFor 挂起
【发布时间】:2012-07-30 04:09:30
【问题描述】:

我在使用 Java 运行外部应用程序时遇到问题。我知道输入和输出流的问题,我正在尝试按如下方式阅读它们:

    ProcessBuilder pb = new ProcessBuilder(args);
    args[args.length - 1] += "<NUL";

    pb.redirectErrorStream(true);
    Process p = pb.start();

    InputStreamReader isr = new InputStreamReader(p.getInputStream());
    BufferedReader input = new BufferedReader(isr);
    while (input.readLine() != null) {
    }       

    p.waitFor();
    input.close();
    isr.close();

我正在执行的命令是 xdg-open 的 URL,所以它不应该等待输入。

这在我的机器上工作十分之九,但有时它只是挂在 pb.start();并且命令没有被执行。

java 线程正在等待进程返回。这是堆栈跟踪:

Name: LinkHandlerExec
State: WAITING on java.lang.UNIXProcess$Gate@356122dc
Total blocked: 0  Total waited: 1

Stack trace: 
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:502)
java.lang.UNIXProcess$Gate.waitForExit(UNIXProcess.java:80)
java.lang.UNIXProcess.<init>(UNIXProcess.java:161)
java.lang.ProcessImpl.start(ProcessImpl.java:81)
java.lang.ProcessBuilder.start(ProcessBuilder.java:468)

这是 strace 告诉我的:

$ sudo strace -p 13255
Process 13255 attached - interrupt to quit
futex(0x7fbb673e49d0, FUTEX_WAIT, 13262, NULL

【问题讨论】:

  • while (input.readLine() != null) {} // 空而只有在您的原始代码中才会这样
  • @Baz,是的,它是相关的。按照那里的建议,我已经尝试在等待后移动边缘的关闭,但这没有效果。
  • @LiuYan - 我已经阅读了 Java World 文章并且意识到了这些问题。那里的代码来自 2000 年,我认为 ProcessBuilder 是一个更好的选择。我试过了,但有类似的问题

标签: java exec


【解决方案1】:

我们也在 CentOS 6.3 JDK 1.6.0_33-b03 上观察到了这样的问题。 调查显示,这是在该 Java 进程发生 OutOfMemoryError 之后发生的。

查看类 java.lang.UNIXProcess 的代码,我想当在 UNIXProcess 构造函数中运行的单独线程中抛出非 IO 异常(例如错误)时,可能会发生此类问题,介于 109 和 130 行之间. 这段代码最好组织成

try {
  .....
} finally {
  gate.exit();
}

,但它被组织为

try {
  ...
} catch (IOException e) {
  gate.setException(e); /*remember to rethrow later*/
  gate.exit();
  return;
}
...
gate.exit(); 

,所以一个非 IO 异常可能会导致 gate.exit() 不被调用,是什么导致主调用者线程在方法 gate.waitForExit() 中永远挂起(第 145 行)。

【讨论】:

    猜你喜欢
    • 2017-08-20
    • 1970-01-01
    • 2018-01-10
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    相关资源
    最近更新 更多