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();

CPP:

#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

データが利用可能であるにもかかわらず、Process の InputStream ブロックから読み取るのはなぜですか?

そうではありません。ここでの問題は、送信側でのバッファリングが原因で、あると思ったときにデータが利用できないことです。

fflush()@MarkkuK.のコメントに従って、またはあなたのようにまったくstdioバッファリングしないように指示することで、それを克服できstdoutます。

于 2013-08-28T06:10:47.903 に答える
0

ここに投稿した別の解決策があります。これは、ストリームInputStream#available()から何かを読み取る前に使用することです。Process

于 2015-01-25T04:19:38.427 に答える