プロセス間通信にパイプを使用する場合、パイプの一端を閉じる目的は何ですか?
例: パイプを使用して2つのプログラム間で単純な文字列を送信する方法
パイプの片側が子プロセスと親プロセスで閉じていることに注意してください。なぜこれが必要なのですか?
パイプを使用して2つのプロセス(親と子)を接続する場合は、フォークの前にパイプを作成します。
フォークは、両方のプロセスがパイプの両端にアクセスできるようにします。これは望ましくありません。
読み取り側は、EOF状態に気付いた場合にライターが終了したことを知るはずです。これは、すべての書き込み側が閉じている場合にのみ発生します。そのため、書き込みFD ASAPを閉じることが最善です。 。
ライターは、開いているFDが多すぎて、おそらく存在する可能性のある開いているFDの制限に達しないようにするために、読み取りFDを閉じる必要があります。その上、そのとき唯一のリーダーが死んだ場合、ライターはSIGPIPEまたは少なくともEPIPEエラー(シグナルの定義方法によって異なる)を受け取ることによってこれについて通知されます。リーダーが複数ある場合、ライターは「本物」が消えたことを検知できず、書き込みを続け、書き込みFDがブロックすることを期待してスタックし、「未使用」のリーダーが何かを読み取ります。
だからここで詳細に何が起こるか:
pipe()
を呼び出し、2つのファイル記述子を取得します。それをrd
とwr
と呼びましょう。fork()
を呼び出します。これで、両方のプロセスにrd
とwr
があります。子プロセスがリーダーであると想定します。
その後
一度に開くことができるファイル記述子の数には制限があります。パイプを開いたままにし、すぐに閉じない場合、FDが不足し、何も開くことができなくなります。パイプではなく、ファイルでもソケットでもありません...
パイプを閉じることが重要になるもう1つの理由は、閉じること自体がアプリケーションにとって意味がある場合です。たとえば、パイプの一般的な使用法は、errno
とfork
を使用して子プロセスから親にexec
を送信することです 外部プログラムを起動します :
fork
を呼び出して子プロセスを作成し、その書き込み端を閉じて、パイプからの読み取りを試みます。exec
を使用して別のプログラムを実行しようとします:exec
が失敗した場合、子はerrno
をパイプに書き込み、親はそれを読み取り、何が問題だったかを認識し、ユーザーに知らせることができます。exec
が成功すると、何も書き込まれずにパイプが閉じます。親のread
関数は、パイプが閉じられ、プログラムが正常に開始されたことを示す0を返します。親がパイプからの読み取りを試みる前にパイプの書き込み側を閉じなかった場合、read
が成功したときにexec
関数が戻らないため、これは機能しません。