web-dev-qa-db-ja.com

ファイル記述子をclose()するとどうなりますか?

ファイル記述子を使用して全体像を取得しようとしています。最初にこれらのファイル記述子を持つprocess1があるとします。

 _process1_
|          |
| 0 stdin  |
| 1 stdout |
| 2 stderr |
|__________|

次に、ファイル記述子1を閉じます。

close(1);

ファイル記述子1は、カーネルのOpen Files Tableのstdout FILE構造に変換(ポイント)します。

上記のコードを使用すると、ファイル記述子1がプロセスのテーブルから削除され、次のようになります。

 _process1_
|          |
| 0 stdin  |
| 2 stderr |
|__________|

しかし、カーネルで何が起こるのでしょうか? stdout FILE構造は割り当て解除されますか? stdoutが特別なファイル(モニター)であり、おそらく他のプロセスによって使用されている場合、それはどのようにして可能ですか?通常のファイル(たとえば、.txt)であるFILE構造についてはどうですか?そのようなファイルが他のプロセスによって使用されている場合はどうなりますか?

16
Pithikos

この場合、多くは起こりません。 stdin、stdout、およびstderrは、すべて同じファイル記述子のクローンになる傾向があります。ファイル記述子の参照カウンタは1つ減少します。同じファイル記述子は通常、プログラムが実行されたシェルによって保持されるため、ファイル記述子を保持する必要があります。

カーネルは、開いているすべてのファイル(inodes)の参照カウントを保持します。参照カウントがゼロより大きい限り、ファイルは保持されます。開いているファイルハンドル用に別のカウンターが保持されることを期待します。これがゼロになると、カーネルはファイルハンドルが使用していたメモリを解放できます。

ファイルへのすべての参照(ディレクトリエントリとファイルハンドル)が削除されると、ファイルシステムコードはiノードに再利用のマークを付けます。ファイルが持っているブロックはすべて、割り当てに使用できるようになります。多くのファイルシステムは、リリース時にiノードのブロックポインタをクリアします。これにより、削除されたファイルの復元が困難になります。ディスクへの更新はバッファリングされ、後で完了する場合があります。

6
BillThor