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()サブプロセスが終了した後でも、無限にブロックします。インスタンスのペアを作成しない場合は、完全に機能します。ブロックを継続する原因となっているioストリームの配管についてはどうですか?PipeThreadp.waitFor()p.waitFor()

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は前のプロジェクトで横になっていたクラスで、別のスレッドで1つのストリームを別のストリームにパイプするためによく使用しました。

で使用したのはこれが初めてSystem.outです。PipeThread読み取り時に渡されるストリームをすべて閉じますEOF。この場合の両方のストリームには私の標準出力が含まれているため、でのデバッグSystem.out.printlnは不可能になります... :(

奇妙なことに、IOException投げられたものはありませんSystem.out.println()、私は調査します。

于 2012-11-13T11:05:04.140 に答える