1

我有以下代码;

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 认为进程仍然处于活动状态。

4

2 回答 2

0

在您的PipeThread代码中,您将永远循环直到 !die - 但您PipeThread.die()在之后调用p.waitFor()- 究竟是什么停止了PipeThread线程?

于 2012-11-13T10:55:42.370 回答
0

因此,经过一番摸索,我意识到发生了什么。p.waitFor()实际上并没有无限期地阻塞,而是我的检查方法失败了;之后的System.out.println()声明p.waitFor()

PipeThread是我在以前的项目中使用的一个类,我经常使用它在单独的线程中将一个流传输到另一个流。

这一定是我第一次使用它System.outPipeThread关闭它在读取时传递的任何流EOF。在这种情况下,两个流都包含我的标准输出,因此System.out.println无法进行调试...... :(

奇怪的是,没有IOException被抛出System.out.println(),我会调查的。

于 2012-11-13T11:05:04.140 回答