web-dev-qa-db-ja.com

開いているファイルの説明とは何ですか?

プロセスをフォークすると、子はその親のファイル記述子を継承します。これが発生すると、子が親のファイル記述子テーブルのコピーを受け取り、それぞれのポインターが同じ開いているファイルの説明を指すことを理解しています。これは、 http://en.wikipedia.org/wiki/File_descriptor のように、ファイルテーブルと同じものですか、それとも他の何かですか?

5
user68207

open system callのドキュメント で答えを見つけました:

オープンファイルの説明という用語は、POSIXでシステム全体のオープンファイルのテーブルのエントリを参照するために使用される用語です。他のコンテキストでは、このオブジェクトは、「オープンファイルオブジェクト」、「ファイルハンドル」、「オープンファイルテーブルエントリ」、またはカーネル開発者の用語では構造体ファイルとも呼ばれます。ファイル記述子が複製されると(dup(2)などを使用して)、複製は元のファイル記述子と同じ開いているファイルの説明を参照し、その結果、2つのファイル記述子はファイルオフセットとファイルステータスフラグを共有します。このような共有はプロセス間でも発生する可能性があります。fork(2)を介して作成された子プロセスは、親のファイル記述子の複製を継承し、それらの複製は同じ開いているファイルの説明を参照します。ファイルの各open(2)は、新しいオープンファイル記述を作成します。したがって、ファイルiノードに対応する複数の開いているファイル記述が存在する可能性があります。

1
user68207

ファイル記述子→ファイルの説明を開く→ディレクトリエントリ
dupopencp

プロセスで開いているファイルからファイルの内容に至るまで、いくつかのレベルの間接参照があります。実装に関しては、これらのレベルは一般に、次のレベルを指すカーネルのデータ構造に変換されます。簡単な実装について説明します。実際の実装では、さらに複雑になる可能性があります。

プロセスで開いているファイルは、小さな非負の整数であるファイル記述子によって指定されます。番号0、1、および2には、従来の意味があります。プロセスは、通常の入力を0(標準入力)から読み取り、通常の出力を1(標準出力)に書き込み、エラーメッセージを2(標準エラー)に書き込むことになっています。これは単なる慣例です:カーネルは気にしません。カーネルは、各プロセスの開いているファイル記述子のテーブルを保持し、これらの小さな整数をファイル記述子構造にマッピングします。 Linuxカーネルでは、この構造は struct fd

ファイル記述子構造には、オープンファイルの説明へのポインタが含まれています。たとえば、プロセスが dup とその仲間を呼び出したとき、またはプロセスがフォークした後など、複数のプロセスから、同じ開いているファイルの説明を指す複数のファイル記述子が存在する可能性があります。ファイル記述子が(異なるプロセスであっても)同じ元のopen(または同様の)システムコールによるものである場合、それらは同じオープンファイル記述を共有します。開いているファイルの説明には、モード(読み取り専用vs読み書き、追加など)、ファイル内の位置など、ファイルを開く方法に関する情報が含まれています。Linuxでは、開いているファイルの説明の構造は struct file

開いているファイルの説明は、ファイルAPIのレベルにあります。次のレベルはfilesystemAPIです。違いは、ファイルAPIがファイルシステムツリーに存在しない匿名パイプやソケットなどのファイルをカバーすることです。ファイルがディレクトリツリー内のファイルである場合、開いているファイルの説明には、ディレクトリエントリへのポインタが含まれています。同じファイルが複数回openedされた場合、同じディレクトリエントリを指す複数の開いているファイルの説明が存在する可能性があります。ディレクトリエントリには、親ディレクトリへのポインタやファイルの場所に関する情報など、ファイルの内容に関する情報が含まれています。 Linuxカーネルでは、ディレクトリエントリは2つのレベルに分割されています。 struct inode これにはファイルメタデータと struct dentry ファイルがディレクトリツリーのどこにあるかを追跡します。

私はこの質問を、主に用語、特に「ファイルテーブル」に関するものとして解釈しています。

初期の実装を見ると、システムで開いているすべてのファイル記述のセットは配列でした。プロセスが新しい開いているファイルの説明を必要とするとき、配列は未使用のスロットをスキャンされ、そのスロットへのポインターが返されました。たとえば、 http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/sys/sys/fio.c の下部にあるfallocを参照してください。 ==

そのシステムでは、「ファイルテーブル」はstruct fileのシステム全体の配列の自然な名前です。

現在、オープンファイルの説明は、固定サイズの配列で未使用のスロットを選択するだけではなく、より柔軟なメカニズムで動的に割り当てられます。システムで開いているすべてのファイル記述のセットは、連続した配列のようなセットアップで配置する必要はありません。したがって、すべての動的メモリ割り当てプールを「テーブル」と見なさない限り、「ファイルテーブル」はもうありません。

ウィキペディアの図の「ファイルテーブル」は、開いているファイルの説明のセットです。ファイル記述子は、ファイルの説明を開くためのポインタの配列へのインデックスです。開いているファイルの説明は常にこれらのポインターを介してアクセスされるため、配列内の数値インデックスでは決してアクセスされないため、ボックスの連続した列としてそれらを描画することは少し誤解を招きます。そして、それを「テーブル」と呼ぶことは、その誤解を招くイメージを補強します。

しかし、それはかなり一般的な使用法なので、すぐになくなるとは思いません。

2
user41515

それが明確ではないので、あなたの質問の内容を理解しようとします。しかし、私が正しく理解していれば、複数のプロセスが同じファイルにどのように書き込むことができるかという質問はありますか? Linuxでは、デフォルトで、ファイルはプロセスによってロックされておらず、複数のプロセスが同じファイルに書き込むことが常に可能です。もちろん、ファイルのフォーマットを壊すリスクがあります。書き込みは一度にバッファになる傾向があります(ほとんどの場合、それはテキストの1行を意味します。ファイルが一般的なログであり、複数のプロセスがそれに書き込んでいる場合は、一種の動作で問題ありません)バッファなしのファイルを使用できますが、ファイルを開いたときに、デフォルト以外の追加オプションを選択する必要があります。

ランダムに開かれたファイルIOは、いくつかのプロセスで開かれることによって実際に混乱する可能性があり、IOのソートは、安全に使用するためにファイルロックを必要とする可能性があります。

もう1つの関連する問題は、プロセスがそのファイルに頻繁にまたはまったく書き込みを行わない場合でも、実行中のプロセスによってファイルが開いたままになっている場合です。 「削除」しても、ファイルは引き続きディスク容量を消費します。プロセスがファイルを閉じてファイルハンドルを解放した後にのみ、使用されているディスク領域が回復されます。

開いているファイルの詳細を学ぶもう1つの場所は、/ procディレクトリ、特に/ proc/PID/fdです。これは、特定のPIDプロセスが開いていたファイルを確認する方法です。

0
Cosmo F