10

私はこの次のシナリオを持っています。

  1. パイプを作ります。

  2. 子プロセスをフォークしました。

  3. 子はパイプの読み取り側を明示的に閉じ、パイプの書き込み側に書き込み、何も閉じずに終了します(終了は、子に代わって開いているすべてのファイル/パイプ記述子を閉じる必要があると思います)。

  4. 親はパイプの書き込み側を明示的に閉じ、 null を返すfgetsまでを使用してパイプの読み取り側から読み取ります。fgetsつまり、完全に読み取ります。

ここで私の質問は、読み取りが完了したら、親がパイプの読み取り側を明示的に閉じる必要があるのはなぜですか? 完全なデータが読み取り側から読み取られたら、システムがパイプを完全に削除するのは賢明ではありませんか?

親で明示的に読み取り終了を閉じることはありませんが、Too many file descriptors遅かれ早かれ、さらにパイプを開くときにエラーが発生します。私の仮定では、書き込み側が閉じられ、データが読み取り側から完全に読み取られると、システムはパイプを自動的に削除するというものでした。パイプから二度カントできないから!

では、データが完全に読み取られ、書き込み終了が閉じられた後、システムがパイプを削除しない理由は何ですか?

4

2 に答える 2

7

子が終了すると、システムがパイプの書き込み端を閉じることは正しいです。forkただし、子が書き込み終了の複製を別のプロセスに渡す場合、そのパイプの別の書き込み終了が開いている可能性があります。

システムは、パイプの一方の端にあるすべての記述子が閉じられたとき(明示的に、または所有プロセスが終了したため)を知ることができるのは事実です。親プロセスがパイプの端にある記述子を閉じようとすると混乱が生じるため、パイプのもう一方の端にあるものを閉じることはまだ意味がありません。また:

  • fdがシステムによって閉じられました。この場合、すでに閉じられているfdを閉じようとするときにエラーが発生します。また
  • fdは再利用されましたが、完全に無関係なfdを閉じているため、さらに悪化しています。

システムの観点からは、一方の端のすべての記述子が閉じられると、パイプが破棄された可能性があるため、そこでの非効率性について心配する必要はありません。さらに重要なのは、ユーザースペースプロセスが一貫したエクスペリエンスを備えている必要があることです。つまり、特に要求されない限り、記述子を閉じないでください。

于 2012-08-06T10:32:10.457 に答える
5

プロセスが終了するまで、ファイル記述子はシステムによって閉じられません。これは、パイプだけでなく、他のファイル記述子にも当てはまります。

データのないパイプ (またはその他のファイル) と閉じたファイル記述子には大きな違いがあります。
ファイル記述子が閉じられると、システムはその番号を新しいファイル記述子に再利用できます。そして、読んでみると、何かが得られます。したがって、ファイル記述子を閉じた後は、それを使用してはなりません。

ここで、データがなくなると、システムが自動的にファイル記述子を閉じると想像してください。これにより、番号を再利用できるようになり、その後の無関係なオープンで番号が取得される可能性があります。データがもうないことをまだ知らないリーダーは、パイプと思われるものから読み取りますが、実際には別のファイルから読み取ります。

于 2012-08-06T10:38:12.547 に答える