2012-08-06 26 views
10

私は以下のシナリオを持っています。書き込み終了が既に終了しているパイプの読み出し側を明示的に閉じる必要がありますか?

  1. 私はパイプを作成します。

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

  3. 子供は明示的にパイプの終わりを読み、(出口が子供に代わって、開いているすべてのファイル/パイプ記述子を閉じる必要があります、私は推測)何を閉じることなく、パイプと出口の書き込み終了に書き込む閉じます。

  4. 親が明示的パイプの書き込み側を閉じ、NULL fgetsfgetsまでのリターンを使用してパイプの読み出し側から読み込みます。つまり、完全に読み取ります。

私の質問は、親がパイプの読み込み終了を明示的に終了する必要があることです。完全なデータが読み終わりから読み込まれると、システムがパイプを完全に削除するのは賢明ではありませんか?

私は親の明示的に読んだ終わりを閉じます。パイプをさらに開いているうちに遅かれ早かれ、エラーToo many file descriptorsがあります。私の仮定は、書き込み終了が閉じられ、データが読み取り終了から完全に読み込まれると、システムがパイプを自動的に削除するということでした。あなたがパイプから2回傾けることはできません!

データが完全に読み込まれ、書き込みが終了したら、システムの背後にある論理的根拠はどうしてパイプを削除しないのでしょうか?

+0

「パイプから2回傾けることはできません!」 –

+0

@KerrekSB私が言ったことは、同じパイプを2回読むことができましたが、2回目のEOFが正しく表示されることでしょうか? –

答えて

7

子が終了すると、システムがパイプの書き込み終了を閉じることは間違いありません。しかし、子がforkであるか、書き込み終了の複製を別のプロセスに渡すと、そのパイプの別の書き込み終了がある可能性があります。

パイプの一端にあるすべてのディスクリプタが(明示的にまたは所有プロセスが終了したために)閉じられたことをシステムが認識できることは、依然として真実です。親プロセスがパイプの終わりに記述子を閉じようとすると混乱を招くため、パイプの他端にあるものを閉じるのはまだ意味がありません。

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

システムの観点からは、一端のすべてのディスクリプタが閉じられるとパイプを破棄してしまう可能性があるので、そこでの非効率性を心配する必要はありません。さらに重要なことは、ユーザー空間プロセスには一貫性のある経験が必要であるということです。具体的に要求されない限り、ディスクリプタを閉じないことを意味します。

5

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

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

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

関連する問題