【问题标题】:Process hanging on the process builder挂在流程构建器上的流程
【发布时间】:2017-02-24 10:29:19
【问题描述】:

我正在使用 java 进程构建器来执行 Windows 外部进程(即 exe 文件)。我必须使用输入流获取进程信息和错误,错误流将其写入一些文本文件。

它有时会工作,有时会意外挂起。

当我调用大约三个外部进程来一一执行时。两个进程工作,它只挂在第三个进程上。

有时我可以看到进程退出值为 0,它给出了一些其他随机值。

我已阅读以下博客并应用相同的逻辑来执行该过程,但不适用于我的场景。

谁能帮我诊断一下这些问题...

//开始启动外部进程 //此代码将从中选择三个参数以顺序执行该过程 //它将通过for循环一一传递进程命令

 Process p =new ProcessBuilder(s)
               .directory(new File(je.getExecution().getWorkingDirectory()))
               .redirectErrorStream(true)
               .redirectOutput(file)
               .start();

p.getOutputStream().close();
int processStatus= p.waitFor();

//如果进程以0正常终止退出

提前谢谢..,

【问题讨论】:

  • 您可能没有使用 stdout/stderr,尽管还有其他陷阱。强烈推荐你阅读javaworld.com/article/2071275/core-java/…
  • @Adam 我正在使用标准输出/标准错误。我的问题是它有时会处理第三个过程。我将依次调用三个过程。我不知道为什么调用第三个进程失败
  • 一些代码怎么样
  • @SouravGanguly 更新了我的问题中的代码。请看一下
  • @SouravGanguly 关于该代码的任何想法

标签: java multithreading jvm deadlock


【解决方案1】:

您所做的整个事情都容易出错,不值得尝试找出所有错误,因为您让生活变得不必要地艰难。

请注意,您正在调用redirectErrorStream(true),但仍在尝试从错误流中读取,这是没有意义的。在这种情况下,错误流将始终为空。也就是说,如果您已经了解重定向,不清楚为什么不直接使用它们,而是创建线程、手动将数据复制到StringWriters 等。

显然,您想使用工作目录je.getExecution().getWorkingDirectory(),启动命令s 并将程序的输出和错误都指向file。这可以很容易地实现

new ProcessBuilder(s)
    .directory(je.getExecution().getWorkingDirectory())
    .redirectErrorStream(true).redirectOutput(file)
    .start()
    .waitFor();

唯一剩下的错误来源是启动的进程可能会等待您这边的输入。由于您显然不想提供输入,因此您可以使用

Process proc = new ProcessBuilder(s)
    .directory(je.getExecution().getWorkingDirectory())
    .redirectErrorStream(true).redirectOutput(file)
    .start();
proc.getOutputStream().close();
proc.waitFor();

表示你不会写任何数据。这不会停止进程,但是当它尝试从其标准输入中读取某些内容时,它会立即获得一个文件结尾而不会阻塞。

可以用什么来证明

Process proc = new ProcessBuilder("cmd", "/c", "pause")
    .redirectErrorStream(true).redirectOutput(file)
    .start();
proc.getOutputStream().close();
proc.waitFor();

【讨论】:

  • 在不挂任何进程的情况下是否可以工作。 redirectOutput(file) 将字符串写入一行而不中断 newLine()。你有什么想法将字符串写入 newLine 吗?
  • 在我的开发 Windows 7 64 位机器中,当我使用您的代码时,它按预期工作。我想在我的部署环境机器 windows 服务器中测试它。希望它会奏效。
  • 有时无法完成进程。
  • 重定向是在操作系统级别处理的,并完全按照写入的方式写入数据,即在子进程生成换行符的位置有一个新行。您逐行读取和写入输出的原始代码也不会引入换行符。可能只会发生隐式转换,因为BufferedReader 将解释各种换行符(\r\n\n\r)和PrintWriter 总是使用平台特定的换行符序列。通常,这不应该是必要的。如果子进程还是偶尔挂起,那肯定是有更深层次的问题了。
  • 显示输出行对我来说并不重要。我只是在写日志以查看调用外部进程时发生的任何错误。有时进程不会以退出值 0 终止。更新了我的问题中的代码。请看一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 2019-12-18
  • 1970-01-01
  • 2013-10-27
  • 1970-01-01
相关资源
最近更新 更多