Linux では、fd の正式名は「ファイル記述子」、中国語名は「ファイル記述子」と呼ばれ、開かれたファイルを効率的に管理するためにカーネルによって作成されるインデックスです。これは実際には、開かれたファイルを参照するために使用される非負の整数です。I/O 操作を実行するすべてのシステム コールは、ファイル記述子を通じて実装されます。
#このチュートリアルの動作環境: linux7.3 システム、Dell G3 コンピューター。
Linux では、fd の正式名は「ファイル記述子」、中国語名は「ファイル記述子」です。ファイル記述子は負ではない整数であり、本質的にはインデックス値です (この文は非常に重要です)。
Linux システム内のすべてのものはファイルとみなされ、ファイルは通常のファイル、ディレクトリ ファイル、リンク ファイル、デバイス ファイル。これらのいわゆるファイルを操作する場合、操作のたびに名前を検索する必要があり、多大な時間と効率がかかります。そのため、Linuxでは各ファイルがインデックスに対応することが規定されており、ファイルを操作したい場合には、直接インデックスを見つけて操作することができます。
ファイル記述子 (ファイル記述子) は、これらのオープンされたファイルを効率的に管理するためにカーネルによって作成されるインデックスであり、オープンされたファイルを参照するために使用される非負の整数 (通常は小さな整数) です。 、I/O 操作を実行するすべてのシステム コールは、ファイル記述子を通じて実装されます。同時に、システムの起動直後は、標準入力が0、標準出力が1、標準誤差が2であることも規定されています。これは、この時点で新しいファイルを開いた場合、そのファイル記述子は 3 になり、別のファイルを開いた場合、ファイル記述子は 4 になることを意味します...
Linux カーネルは、開いているすべてのファイルを処理します。ファイル記述子テーブルとは、各ファイル記述子と開いているファイルとの関係をインデックスとして格納したもので、簡単に理解すると以下のような配列であり、ファイル記述子(インデックス)はファイル記述子テーブルの配列の一番下にあります。配列の内容は、ファイルを 1 つずつ開くためのポインターです。
上記は単なる理解ですが、実際、ファイル記述子に関して、Linux カーネルは 3 つのデータ構造を維持しています:
Linux プロセスが実行された後PCB 制御ブロックがカーネル空間に作成されます。PCB 内にはファイル記述子テーブルがあり、現在のプロセスで使用可能なすべてのファイル記述子、つまり現在のプロセスで開いているすべてのファイルが記録されます。プロセス レベルの記述子テーブルの各エントリには、単一のプロセスで使用されるファイル記述子に関する情報が記録されます。プロセスは互いに独立しています。あるプロセスがファイル記述子 3 を使用する場合、別のプロセスもそれを使用できます。 3。プロセス レベルのファイル記述子テーブルに加えて、システムはオープン ファイル テーブルと i ノード テーブルという他の 2 つのテーブルも維持する必要があります。これら 2 つのテーブルには、開いている各ファイルの開いているファイル ハンドルが格納されます。開いているファイル ハンドルには、開いているファイルに関連するすべての情報が保存されます。
システムレベルのオープンファイル記述子テーブル:
ファイル システムの i ノード テーブル:
ファイル記述子、開いているファイル ハンドルとそれらの間の関係i-nodes は以下のとおりです。
これは、同じプロセスの異なるファイル記述子が同じファイルを指すことができ、異なるプロセスが同じファイル記述子を持つことができ、異なるプロセスの同じファイル記述子が異なるファイルを指すことができることを意味します。 (3 つの特殊ファイル 0、1、および 2 を除いて、これは一般的に当てはまります); 異なるプロセスの異なるファイル記述子が同じファイルを指すこともあります。
Linux でファイルを開く例
たとえば、vim test.py を使用して開きます。 Linux 上のファイルを開いたままにし、新しいシェルを開き、コマンド pidof vim を入力して vim プロセスの PID 番号を取得し、次に ll /proc/$pid/fd ファイル記述子の vim プロセスリストで使用される pid 番号を表示します。
/dev/pts は、リモート ログイン (telnet、ssh など) 後に作成されたコンソール デバイス ファイルが配置されるディレクトリです。 Xshell を介してリモートでログインしたため、標準入力 0、標準出力 1、および標準エラー 2 のファイル記述子はすべて、仮想端末コンソール /dev/pts/6 を指します。 新しく開いた test.py のファイル記述子を見ると、4 となっています。3 から開始することに同意しましたか?
私はこのことに長い間悩まされてきました。さまざまな情報を確認した結果、偉い人の助けを借りてフォーラムでついに原因を見つけました。中国語で見つからない場合は、まだ英語で検索してみる必要があります。 vim のようなエディタの原則は、まずソース ファイルを開いてコピーし、次にソース ファイルを閉じてから独自のコピーを開き、ファイルを変更して保存した後、コピーの名前を直接変更してソース ファイルを上書きすることです。したがって、ソース ファイルを開くときは、ファイル記述子 3 を使用して、独自のコピーを開きます。次に、ファイル記述子 4 を使用して、ソース ファイル、ファイル記述子を閉じます。 3 が解放され、確認すると 4 だけが残っており、vim が作成したコピーファイルを指しています。これは単なる一般的なアイデアです。vim の実装原理をさらに詳しく説明するために、オールト星雲アンバサダーが、当時私が見たフォーラムの情報のスクリーンショットを示します。リンクはここにあります: StackOverFlow。
信じられない場合は、tail などの別のプロセスを試してみてください。
使用 tail -f test.py Linux 上でファイルを開いて開いたままにして、新しいシェルを開いてコマンドを入力します pidof tail Get tail pid ll /proc/$pid/fd 末尾プロセスで使用されるファイル記述子のリストを確認すると、ファイル記述子が実際に 3# から使用されていることがわかります。 ## 。 Tail はエディターでファイルを変更しないため、ソース ファイルはファイル記述子を使用して直接開かれます。実際、ll /proc/$pid/fd コマンドを使用すると、現在実行中のプロセスのファイル記述子の使用状況を取得できます。
#拡張知識: Linux 構成システムでオープンされるファイル記述子の最大数
( 1 ) システムレベルの制限理論的には、システム メモリがある限り多くのファイル記述子を開くことができますが、実際には、カーネルがそれに応じて処理します。一般に、開くファイルの最大数はシステム メモリの 10% になります (KB 単位で計算) 、これはシステムレベルの制限と呼ばれます。この数値は、cat /proc/sys/fs/file-max または sysctl -a | grep fs.file-max コマンドで確認できます。 システム レベルの制限を変更するには、一時的な変更と永続的な変更の 2 つの方法があります。 一時的な変更: セッションの切断またはシステムの再起動 後で元の設定が復元されます。コマンド sysctl -w fs.file-max=xxxx を使用します。ここで、xxxx は設定する番号です。 永続的な変更: vim で /etc/sysctl.conf ファイルを編集し、最後に fs.file-max=xxxx を追加します。 xxxx 設定する番号です。保存して終了した後、sysctl -p コマンドを使用して有効にする必要があります。 (2) ユーザーレベルの制限 同時に、各プロセスが消費するファイルリソースを制御するために、カーネル単一プロセスの最大ファイルも開きます。デフォルトの制限はユーザーレベルの制限です。 32 ビット システムのデフォルト値は通常 1024、64 ビット システムのデフォルト値は通常 65535 です。これを表示するには、ulimit -n コマンドを使用できます。 ユーザーレベルの制限を変更するには、一時的な変更と永続的な変更の 2 つの方法があります。 一時的な変更: セッションの切断またはシステムの再起動 後で元の設定が復元されます。コマンド ulimit -SHn xxxx を使用して変更します。ここで、xxxx は設定する番号です。 永続的な変更: vim で /etc/security/limits.conf ファイルを編集し、hard nofile xxxxおよび soft nofile xxxx (xxxx は設定する番号)。保存して終了。ハードとソフトの違いについては下記参考リンク5枚目をご参照ください。 関連する推奨事項: 「Linux ビデオ チュートリアル 」
以上がLinux fdとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。