次のパイプラインを実行している場合:
cat my_large_file.txt | head | wc
プロセスはほぼ即座に停止します。わかった。
しかし、Javaプログラムを実行すると
java MyProgramReadALargeFile my_large_file.txt | head | wc
'wc'からの出力はに出力されますstdout
が、Javaプログラムはまだ実行中です。パイプラインが閉じられたことをどのように検出できますか?
ありがとう、
ほとんどのUNIXユーティリティはSIGPIPEに注意を払っています。これは、受信すると、プロセスが書き込んでいるパイプストリームがもう一方の端でリッスンしていないことを示すため、作業を続ける必要はありません。
「javaposixsignals」のようなものを検索すると、Javaコードにシグナルハンドラーを追加できるライブラリがいくつか生成されます。
'head' は最初の 10 行の後にストリームを閉じるため、'head' と 'wc' が終了している間も Java がまだ実行されているのは正常です。System.out がまだ開いている場合は、おそらく Java コードでテストできますが、これが信頼できる方法であるとは思えません。おそらくパイプの OS 実装と System.out の JVM 実装に依存します (ストリームを本当に閉じるのか、/dev/null に渡すだけなのか)。
(十分な大きさのファイルを cat し、'head' が完了した後も 'cat' プロセスが実行され続けるかどうかを確認しましたか?)
Javaプログラムの観点からは、System.outを閉じるとは思えません。/ dev / nullにリダイレクトされる可能性がありますが、Javaプログラムの出力ストリーム(exit())のリッスンを停止する方が簡単です。
'cat'のソースを調べて、出力ストリームの状態を検出するかどうかを確認できます。その場合は、「MyProgramReadALargeFile」プログラムに同様のコードを配置する必要があります。そうしないと、ヘッドがパイプに供給するプロセスが検出できないことをしている可能性があります。
'cat'の例が終了する速度が疑わしい場合は、次のことを試してください。
cat my_large_file.txt > /dev/null
そして、それが同じくらい速いかどうかを確認します。