【发布时间】:2012-11-01 19:15:02
【问题描述】:
我有以下代码;
String[] cmd = { "bash", "-c", "~/path/to/script.sh" };
Process p = Runtime.getRuntime().exec(cmd);
PipeThread a = new PipeThread(p.getInputStream(), System.out);
PipeThread b = new PipeThread(p.getErrorStream(), System.err);
p.waitFor();
a.die();
b.die();
PipeThread 类非常简单,所以我将其全部包含在内;
public class PipeThread implements Runnable {
private BufferedInputStream in;
private BufferedOutputStream out;
public Thread thread;
private boolean die = false;
public PipeThread(InputStream i, OutputStream o) {
in = new BufferedInputStream(i);
out = new BufferedOutputStream(o);
thread = new Thread(this);
thread.start();
}
public void die() { die = true; }
public void run() {
try {
byte[] b = new byte[1024];
while(!die) {
int x = in.read(b, 0, 1024);
if(x > 0) out.write(b, 0, x);
else die();
out.flush();
}
}
catch(Exception e) { e.printStackTrace(); }
try {
in.close();
out.close();
}
catch(Exception e) { }
}
}
我的问题是这样的; p.waitFor() 无休止地阻塞,即使在子进程终止后也是如此。如果我不创建一对PipeThread 实例,那么p.waitFor() 可以完美运行。导致p.waitFor() 继续阻塞的 io 流的管道是什么?
我很困惑,因为我认为 IO 流是被动的,无法保持进程处于活动状态,或者让 Java 认为进程仍然处于活动状态。
【问题讨论】:
-
你
start()你的线程了吗?在您粘贴到此处的代码中,您没有。 -
@infgeoax
start()在构造函数中被调用。这可能是不好的做法,但它就在那里:) -
试试
private volatile boolean die? -
哦,哇,我才意识到发生了什么……这很有趣,我会回答我自己的问题。希望有人会和我一起笑...
-
当 read() 返回 -1 时,通常仅仅调用一个方法是不够的。您应该跳出循环并关闭流。在循环内使用 BufferedOutputStream 和刷新也没什么意义。
标签: java runtime subprocess stdio