ProcessBuilder调用的Java进程永远休眠

ProcessBuilder调用的Java进程永远休眠,java,object,concurrency,process,Java,Object,Concurrency,Process,我正在开发一个大系统,我完全用Java编写。但我也在某个时刻与一个C程序进行通信,将它作为一个进程运行,通过文件系统向它传递一些输入,然后等待它完成从中读取结果。现在,除了这个,我什么也做不了。我没有时间通过API或类似的东西来链接它们 在我需要调用这个过程两次以获得结果之前,这个过程一直运行良好。我第一次调用时,它工作得很好。然而,对于第二次调用,进程只是挂起!我不知道它是否在睡觉,是否在等待信号,但我不明白它为什么要这样做 以下是执行调用的方法: public synchronized bo

我正在开发一个大系统,我完全用Java编写。但我也在某个时刻与一个C程序进行通信,将它作为一个进程运行,通过文件系统向它传递一些输入,然后等待它完成从中读取结果。现在,除了这个,我什么也做不了。我没有时间通过API或类似的东西来链接它们

在我需要调用这个过程两次以获得结果之前,这个过程一直运行良好。我第一次调用时,它工作得很好。然而,对于第二次调用,进程只是挂起!我不知道它是否在睡觉,是否在等待信号,但我不明白它为什么要这样做

以下是执行调用的方法:

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) { }
}