ProcessBuilder调用的Java进程永远休眠
我正在开发一个大系统,我完全用Java编写。但我也在某个时刻与一个C程序进行通信,将它作为一个进程运行,通过文件系统向它传递一些输入,然后等待它完成从中读取结果。现在,除了这个,我什么也做不了。我没有时间通过API或类似的东西来链接它们 在我需要调用这个过程两次以获得结果之前,这个过程一直运行良好。我第一次调用时,它工作得很好。然而,对于第二次调用,进程只是挂起!我不知道它是否在睡觉,是否在等待信号,但我不明白它为什么要这样做 以下是执行调用的方法:ProcessBuilder调用的Java进程永远休眠,java,object,concurrency,process,Java,Object,Concurrency,Process,我正在开发一个大系统,我完全用Java编写。但我也在某个时刻与一个C程序进行通信,将它作为一个进程运行,通过文件系统向它传递一些输入,然后等待它完成从中读取结果。现在,除了这个,我什么也做不了。我没有时间通过API或类似的东西来链接它们 在我需要调用这个过程两次以获得结果之前,这个过程一直运行良好。我第一次调用时,它工作得很好。然而,对于第二次调用,进程只是挂起!我不知道它是否在睡觉,是否在等待信号,但我不明白它为什么要这样做 以下是执行调用的方法: public synchronized bo
public synchronized boolean processCommand(List command) {
try {
ProcessBuilder pb = new ProcessBuilder(command);
Process p = pb.start();
p.waitFor();
p.destroy();
} catch(Exception ex) { return false; }
return true;
}
我真的不需要与stdout或stdin通信。我只需要进程运行并完成它的工作。但它只是挂起时,调用进程正在等待它只有第二次我调用它!
我的调用代码只是简单地生成命令列表并从另一个java对象调用此方法
当C程序的输入较小时,对processCommand(List命令)方法的两个调用都可以正常工作。这是标准输入法还是标准输出法的问题
这简直快把我逼疯了!有人知道这件事吗?我感谢你的赞扬:)
更新:
以下是基于@Gray提到的解决方案:
我只需要排出InputStream,可能还有ErrorStream:
public synchronized boolean processCommand(List command) {
try {
ProcessBuilder pb = new ProcessBuilder(command);
Process p = pb.start();
handleStream(p.getInputStream);
handleStream(p.getErrorStream);
p.waitFor();
p.destroy();
} catch(Exception ex) { return false; }
return true;
}
尝试遵循建议的解决方案(原始链接似乎不可用;可以找到存档版本,尽管示例代码的引用链接仍然指向原始站点…) 处理这种情况的最佳策略是在调用waitFor之前启动一个线程,该线程将在适当的时间段后中断当前线程。TimerTask正是为这种情况而设计的,而waitFor在大多数情况下对中断非常敏感。[参考原始链接以获取示例] [……] Java6API明确指出,未能及时“读取子流程的输出流可能导致子流程阻塞,甚至死锁” [……] 今天处理这个问题的安全方法是,通过调用Process.getOutputSteam、Process.getInputStream和Process.getErrorStream提供的每个流上的close,显式地清理流程的每个实例,然后调用Process.destroy,即使流程已经终止
您是否起诉正在调用的进程已退出?可能它正在等待用户输入,而您并不期望这样?如果流程有输出,您可能需要先排空输出,然后才能等待流程完成?可能是输出阻塞了它?是否可能C程序从未退出(例如,等待进一步的输入)?在这种情况下,您仍然在
synchronized
方法中(在p.waitFor()
),在输入method@Gray这个过程实际上并没有退出。我调用的C程序显示在ps-a中,如果我手动终止该进程,Java程序将继续,这意味着C程序被某种方式阻止,当然它也会阻止Java程序,因为我使用了p.waitFor()。@Gray你说的输出是什么意思?我该怎么做?链接死了真可惜。
public void handleStream(InputStream input) {
try {
int c;
while( (c=input.read())!= -1) { //Anything }
} catch(Exception ex) { }
}