Unix のパイプにはバッファがあるため、右側のプロセス (RSP) がデータを消費しなくても、左側のプロセス (LSP) はブロックする前に数キロバイトを生成できます。
その後、バッファがいっぱいになると、LSP は最終的にブロックされます。 RSP がデータを読み取ると、バッファ スペースの一部または全部が解放され、LSP が操作を再開します。
2 つのプロセスではなく 3 つのプロセスがある場合、状況は多かれ少なかれ同じです。つまり、より高速なプロデューサーがより低速なコンシューマーによってブロックされます。そして明らかに、パイプが空になると、より速い消費者はより遅い生産者によってブロックされます:すべての中で最も遅い生産者であるユーザーを待っている対話型シェルについて考えてみてください。
たとえば、次のコマンド:
$ yes | cat | more
more
以降 画面がいっぱいになるとブロックし、ユーザーがキーを押すまで cat
プロセスは出力バッファをいっぱいにしてストールし、その後 yes
プロセスはバッファをいっぱいにし、ストールします。ユーザーが続行するのを待っているすべてが、本来あるべき姿です。
PS:興味深い事実として:more
プロセスは終了しますか?そのパイプの右側は閉じているので、cat
プロセスは SIGPIPE
を取得します 信号(パイプに再び書き込む場合)と死ぬでしょう。 yes
でも同じことが起こります 処理する。すべてのプロセスは死ぬべきです。
A には B へのパイプがあり、B には C へのパイプがあります。各パイプにはバッファーがあります。 B と C が読み取ろうとするとブロックされ、使用可能な入力がありません (ストリームの終わりが入力としてカウントされます)。書き込む出力があるが、パイプのバッファがいっぱいの場合、A と B はブロックします。
3 つのプロセスはすべて、できるだけ多くの CPU を使用して同時に実行されます。 OS は、パイプ バッファがそれぞれ使い尽くされた場合、必要に応じて読み取り/書き込みシステム コールでそれらをブロックします。
つまり、レートは消費レートと生産レートの両方の最小値です。コンシューマーの方が高速な場合、パフォーマンスはプロデューサーによって駆動され、vv.