直到终止Java子进程时不写其输出(java subprocess does not write i

2019-10-18 09:20发布

我已经写了这个简单的测试用例来描述我遇到的问题:

我创建从Java子进程,并同时启动,因为它是从子的标准输出读取应尽快编写的每一个行线。

我得到的却是,当它终止子输出完全写入。 下面是输出:

Mon Jul 15 19:17:13 CEST 2013: starting process
Mon Jul 15 19:17:14 CEST 2013: process started
Mon Jul 15 19:17:14 CEST 2013: waiting for process termination
Mon Jul 15 19:17:14 CEST 2013: readerThread is starting
Mon Jul 15 19:17:19 CEST 2013: process terminated correctly
Mon Jul 15 19:17:19 CEST 2013: Thread[Thread-0,5,main] got line: foo(7)
Mon Jul 15 19:17:19 CEST 2013: Thread[Thread-0,5,main] got line: foo(49)
Mon Jul 15 19:17:19 CEST 2013: Thread[Thread-0,5,main] got line: foo(73)
Mon Jul 15 19:17:19 CEST 2013: Thread[Thread-0,5,main] got line: foo(58)
Mon Jul 15 19:17:19 CEST 2013: Thread[Thread-0,5,main] got line: foo(30)
Mon Jul 15 19:17:19 CEST 2013: readerThread is terminating

与此代码:

public class MiniTest {
    static void println(String x) {
        System.out.println(new Date() + ": " + x);
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder("bin/dummy", "foo", "5");

        println("starting process");
        Process p = pb.start();
        println("process started");

        new ReaderThread(p).start();

        println("waiting for process termination");
        p.waitFor();
        println("process terminated correctly");
    }

    static class ReaderThread extends Thread {
        private Process p;

        public ReaderThread(Process p) {
            this.p = p;
        }

        public void run() {
            println("readerThread is starting");
            BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            try {
                while((line = r.readLine()) != null) {
                    println(this + " got line: " + line);
                }
            } catch(IOException e) {
                println("read error: " + e);
            }
            println("readerThread is terminating");
        }
    }
}

注意:子过程很简单,它输出线每隔第二,对于一个指定的abount的迭代(并且当在命令行上进行测试,它这样做):

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    char *f = argv[1];
    int n = atoi(argv[2]);
    while(n-- > 0) {
        printf("%s(%d)\n", f, rand() % 100);
        sleep(1);
    }
    return 0;
}

Answer 1:

通过询问周围,对这个问题研究找到了答案。

这个问题无法轻易解决,但显然这是一个libc中的问题。 如果输出是不是tty / PTY,缓冲是不是线。

有迹象表明,允许解决这个问题,例如像stdbuf或无缓冲(由期望的那样)外部程序或脚本但是。

详细说明: 管道发球时标准输出的力线缓冲



文章来源: java subprocess does not write its output until it terminates