ホームページ  >  記事  >  運用・保守  >  Linux fdとは何ですか

Linux fdとは何ですか

青灯夜游
青灯夜游オリジナル
2022-05-09 16:24:349360ブラウズ

Linux では、fd の正式名は「ファイル記述子」、中国語名は「ファイル記述子」と呼ばれ、開かれたファイルを効率的に管理するためにカーネルによって作成されるインデックスです。これは実際には、開かれたファイルを参照するために使用される非負の整数です。I/O 操作を実行するすべてのシステム コールは、ファイル記述子を通じて実装されます。

Linux fdとは何ですか

#このチュートリアルの動作環境: linux7.3 システム、Dell G3 コンピューター。

Linux では、fd の正式名は「ファイル記述子」、中国語名は「ファイル記述子」です。ファイル記述子は負ではない整数であり、本質的にはインデックス値です (この文は非常に重要です)。

Linux のファイル記述子 (fd)

Linux システム内のすべてのものはファイルとみなされ、ファイルは通常のファイル、ディレクトリ ファイル、リンク ファイル、デバイス ファイル。これらのいわゆるファイルを操作する場合、操作のたびに名前を検索する必要があり、多大な時間と効率がかかります。そのため、Linuxでは各ファイルがインデックスに対応することが規定されており、ファイルを操作したい場合には、直接インデックスを見つけて操作することができます。

ファイル記述子 (ファイル記述子) は、これらのオープンされたファイルを効率的に管理するためにカーネルによって作成されるインデックスであり、オープンされたファイルを参照するために使用される非負の整数 (通常は小さな整数) です。 、I/O 操作を実行するすべてのシステム コールは、ファイル記述子を通じて実装されます。同時に、システムの起動直後は、標準入力が0、標準出力が1、標準誤差が2であることも規定されています。これは、この時点で新しいファイルを開いた場合、そのファイル記述子は 3 になり、別のファイルを開いた場合、ファイル記述子は 4 になることを意味します...

Linux カーネルは、開いているすべてのファイルを処理します。ファイル記述子テーブルとは、各ファイル記述子と開いているファイルとの関係をインデックスとして格納したもので、簡単に理解すると以下のような配列であり、ファイル記述子(インデックス)はファイル記述子テーブルの配列の一番下にあります。配列の内容は、ファイルを 1 つずつ開くためのポインターです。

Linux fdとは何ですか

上記は単なる理解ですが、実際、ファイル記述子に関して、Linux カーネルは 3 つのデータ構造を維持しています:

  • プロセス レベルのファイル記述子テーブル
  • システム レベルのオープン ファイル記述子テーブル
  • ファイル システムの I ノード テーブル

Linux プロセスが実行された後PCB 制御ブロックがカーネル空間に作成されます。PCB 内にはファイル記述子テーブルがあり、現在のプロセスで使用可能なすべてのファイル記述子、つまり現在のプロセスで開いているすべてのファイルが記録されます。プロセス レベルの記述子テーブルの各エントリには、単一のプロセスで使用されるファイル記述子に関する情報が記録されます。プロセスは互いに独立しています。あるプロセスがファイル記述子 3 を使用する場合、別のプロセスもそれを使用できます。 3。プロセス レベルのファイル記述子テーブルに加えて、システムはオープン ファイル テーブルと i ノード テーブルという他の 2 つのテーブルも維持する必要があります。これら 2 つのテーブルには、開いている各ファイルの開いているファイル ハンドルが格納されます。開いているファイル ハンドルには、開いているファイルに関連するすべての情報が保存されます。

システムレベルのオープンファイル記述子テーブル:

  • 現在のファイルオフセット (read() および write() を呼び出すとき、または lseek () を直接使用するときに更新されます修正)
  • ファイルをオープンする際の識別(open()のflagsパラメータ)
  • ファイルアクセスモード(open()呼び出し時に設定される読み取り専用モード、書き込み専用モードなど) または、読み取り-write モード)
  • シグナル ドライバーに関する設定
  • ファイルの i ノード オブジェクトへの参照、つまり i ノード テーブル ポインター

ファイル システムの i ノード テーブル:

  • ファイル タイプ (例: 通常のファイル、ソケット、または FIFO) とアクセス許可
  • ファイル 保持されているロックのリスト
  • ファイルのさまざまな属性 (さまざまな種類の操作に関連付けられたファイル サイズやタイムスタンプなど)

ファイル記述子、開いているファイル ハンドルとそれらの間の関係i-nodes は以下のとおりです。

Linux fdとは何ですか

  • プロセス A では、ファイル記述子 1 と 20 は両方とも、23 というラベルが付いた同じオープン ファイル テーブル エントリを指します (オープン ファイル テーブル内のインデックス 23 の配列要素を指します)。これは、次のような原因が考えられます。同じファイルに対して dup()、dup2()、fcntl() を呼び出すか、open() 関数を複数回呼び出します。
  • プロセス A のファイル記述子 2 とプロセス B のファイル記述子 2 は両方とも同じファイルを指します。これは、fork() を呼び出した後に発生する可能性があります (つまり、プロセス A と B は親子プロセス関係にあります)。または、異なるプロセスが open() 関数を単独で呼び出して同じファイルを開く場合、そのプロセス内の記述子は、他のプロセスがファイルを開くために使用したものと同じ記述子に割り当てられます。
  • プロセス A の記述子 0 とプロセス B の記述子 3 は、それぞれ異なるオープン ファイル テーブル エントリを指しますが、これらのテーブル エントリはすべて、i ノード テーブル (ラベル 1976) の同じエントリを指します。 , これらは同じファイルを指します。これは、各プロセスが同じファイルに対して独自の open() 呼び出しを行うために発生します。同じプロセスが同じファイルを 2 回開いた場合にも、同様の状況が発生します。

これは、同じプロセスの異なるファイル記述子が同じファイルを指すことができ、異なるプロセスが同じファイル記述子を持つことができ、異なるプロセスの同じファイル記述子が異なるファイルを指すことができることを意味します。 (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。

Linux fdとは何ですか

信じられない場合は、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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。