11

爪哇:

Process p = Runtime.getRuntime().exec("myCommand");
final InputStream in = p.getInputStream();

new Thread()
{
    public void run()
    {
        int b;
        while ((b = in.read()) != -1) // Blocks here until process terminates, why?
            System.out.print((char) b);
    }
}.start();

共产党:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    printf("round 1\n");

    // At this point I'd expect the Java process be able
    // to read from the input stream.

    sleep(1);

    printf("round 2\n");

    sleep(1);

    printf("round 3\n");

    sleep(1);

    printf("finished!\n");

    return 0;

    // Only now InputStream.read() stops blocking and starts reading.
}

InputStream.read() 的文档指出:

此方法会一直阻塞,直到输入数据可用、检测到流结束或引发异常。

是的,我知道这一点(因此与 linux 相关?):

java.lang.Process:由于一些原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能导致子进程阻塞,甚至死锁。

我的问题是:

  1. 为什么 InputStream.read() 阻塞虽然我应该在进程开始后立即有可用的数据?我在两边都遗漏了什么吗?

  2. 如果它与 linux 相关,有没有办法从进程的输出流中读取而不阻塞?

4

2 回答 2

11

Why does reading from Process' InputStream block although data is available

It doesn't. The problem here is that data isn't available when you think it is, and that's caused by buffering at the sender.

You can overcome that with fflush() as per @MarkkuK.'s comment, or by telling stdio not to buffer stdout at all, as per yours.

于 2013-08-28T06:10:47.903 回答
0

我在这里发布了另一个解决方案,它包括在从流中InputStream#available()读取任何内容之前使用。Process

于 2015-01-25T04:19:38.427 回答