Mat*_*t D 32 java linux crash multithreading processbuilder
我一直在尝试使用Java的ProcessBuilder在Linux中启动应该"长期"运行的应用程序.该程序运行的方式是启动一个命令(在这种情况下,我正在启动一个媒体播放应用程序),允许它运行,并检查以确保它没有崩溃.例如,检查PID是否仍处于活动状态,然后重新启动该进程(如果已经死亡).
我现在遇到的问题是PID在系统中仍然存在,但应用程序的GUI挂起.我尝试将ProcessBuilder(cmd).start()转换为一个单独的线程,但这似乎并没有解决任何问题,正如我希望的那样.
基本上结果是,对于用户来说,程序APPEARS已经崩溃,但是杀死驱动ProcessBuilder.start()进程的Java进程实际上允许创建的进程恢复其正常行为.这意味着Java应用程序中的某些东西干扰了生成的进程,但此时我完全不知道是什么.(因此为什么我尝试将它分成另一个线程,似乎没有解决任何问题)
如果有人有任何意见/想法,请让我知道,因为我不能为我的生活想到如何解决这个问题.
编辑:我不关心从Process创建的I/O流,因此没有采取任何措施来解决这个问题 - 这是否会导致流程本身挂起?
nos*_*nos 35
如果进程写入stderr或stdout,并且你没有读它 - 它只会"挂起",在写入stdout/err时会阻塞.使用shell将stdout/err重定向到/ dev/null或使用redirectErrorStream(true)合并stdout/err并生成从进程的stdout读取的另一个线程
Syn*_*r0r 12
你想要的伎俩?
不要从ProcessBuilder.start()启动您的进程.不要试图搞乱Java中的流重定向/消费(特别是如果你不给它任何关于它的话;)
使用ProcessBuilder.start()启动一个吞噬所有输入/输出流的小shell脚本.
像这样的东西:
#!/bin/bash
nohup $1 >/dev/null 2>error.log &
Run Code Online (Sandbox Code Playgroud)
那就是:如果你不关心stdout并且仍然想将stderr(对吗?)记录到文件中(这里是error.log).
如果您甚至不关心stderr,只需将其重定向到stdout:
#!/bin/bash
nohup $1 >/dev/null 2>1 &
Run Code Online (Sandbox Code Playgroud)
你从Java调用那个小脚本,将它作为一个参数给你想要运行的进程的名称.
如果在Linux上运行的将stdout和stderr重定向到/ dev/null的进程仍然产生任何东西,那么你就有了一个破坏的,不符合规范的Linux安装;)
换句话说:上面的Just Works [TM]并且摆脱了有问题的"你需要在这个和那个命令中消耗流量而不是Java特定的无意义".
Hec*_*tor 11
如果它不处理输出,则运行该进程的线程可能会阻塞.这可以通过生成一个读取进程输出的新线程来完成.
final ProcessBuilder builder = new ProcessBuilder("script")
.redirectErrorStream(true)
.directory(workDirectory);
final Process process = builder.start();
final StringWriter writer = new StringWriter();
new Thread(new Runnable() {
public void run() {
IOUtils.copy(process.getInputStream(), writer);
}
}).start();
final int exitValue = process.waitFor();
final String processOutput = writer.toString();
Run Code Online (Sandbox Code Playgroud)
在遇到类似的问题后,我偶然发现了这件事.同意nos,您需要处理输出.我有这样的事情:
ProcessBuilder myProc2 = new ProcessBuilder(command);
final Process process = myProc2.start();
Run Code Online (Sandbox Code Playgroud)
它工作得很好.产生的过程甚至输出了一些输出但不多.当我开始输出更多时,似乎我的过程甚至不再被启动了.我更新到这个:
ProcessBuilder myProc2 = new ProcessBuilder(command);
myProc2.redirectErrorStream(true);
final Process process = myProc2.start();
InputStream myIS = process.getInputStream();
String tempOut = convertStreamToStr(myIS);
Run Code Online (Sandbox Code Playgroud)
它又开始工作了.(请参阅此链接以获取convertStreamToStr()代码:http://singztechmusings.wordpress.com/2011/06/21/getting-started-with-javas-processbuilder-a-sample-utility-class-to-interact-with -linux-from-java-program /)