1990年に初めてUNIXシステムでアカウントを借りたとき、ファイルの制限が1024に達したため、これを問題として考えたことはありません。
30年が過ぎた今日、(ソフト)制限は1024にすぎません。
1024年の歴史的な理由は、資源が不足しているためだと思います。たとえ彼の証拠を実際に見つけることはできませんが。
私のラップトップの制限は(2^63-1)です:
$ cat /proc/sys/fs/file-max
9223372036854775807
今日、私が見る数字は1990年の1,024人ほど衝撃的です。私のシステムのハード制限()はulimit -Hn
1048576にさらに制限されています。
しかし、なぜ制限があるのですか? RAMを限られたリソースにするのはどうですか?
私はUbuntu 20.04(2020年から)とHPUX B.11.11(2000年から)でこれを実行しました。
ulimit -n `ulimit -Hn`
Ubuntuでは、この制限は1024から1048576に増えます。 HPUXでは、60から1024に増加します。どちらの場合も、メモリ使用量に違いはありませんps -edalf
。不足しているリソースがRAMでない場合、それは何ですか?はい足りない資源はどうですか?
私は私や私のユーザーに役立つ1024制限を経験したことがありません。むしろ、それは私のユーザーが説明できず、自分で修正できないエラーの根本的な原因でしたulimit -n 1046576
。タスクを実行する前に、すぐにクラッシュを考えないでください。
制限が役に立つことがわかりますみんなプロセスが大まかに実行された場合にシステム全体がクラッシュしないようにするプロセスのメモリサイズ。しかし、これがファイルの制限にどのように適用されるかはわかりません。
1990年に戻ると、どのような状況で(通常のメモリ制限ではなく)1024制限が役に立ちましたか?今日も同様の状況がありますか?
答え1
@patbarronはまだ自分のコメントを回答として投稿していませんが、本当に素晴らしいです。答えを探している人がいるなら、ここにいます。
彼が書いた:
たとえば、7版のソースコードを見ることができます(minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/sys/h/user.h)もともとどのように実装されているかを確認してください。 「NOFILE」はプロセスごとに開かれたファイルの最大数で、各プロセスが割り当てるデータ構造のサイズに影響します。これらの構造は、実際に使用されているかどうかに関係なくメモリを占有します。繰り返しますが、これはもはや行われていないため、ほとんど歴史的に興味深いものですが、それはその起源に関する追加の文脈を提供することができます。
別の定数「NFILE」は、システム全体(すべてのプロセス/ユーザー)の最大オープンファイル数であり、各プロセスのオープンファイルテーブルには「ファイル」構造へのポインタが含まれています。minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/sys/conf/cc。これは、システム全体のオープンファイルテーブルのサイズを決定するコンパイル時定数でもあります(実際に使用されているかどうかにかかわらず、メモリを消費することもあります)。
これは歴史的な理由があることを示しています。 NOFILEファイル記述子は、使用するかどうかにかかわらず、各プロセスで維持されます。 RAMが足りない場合は、未使用のメモリを保持しないようにしたいと思います。最近では、RAMが安くなるだけでなく、事前注文ももはやそうではありません。
ulimit -n
それは私の観察を確認します。最大値までの高さではなく、1024に維持する理由が見つかりませんulimit -n $(ulimit -Hn)
。ファイル記述子が実際に使用されている場合にのみメモリが占有されます。
答え2
私が知る限り、そうです。ファイルの最大カーネルハード制限はメモリ割り当てポリシーによるものです(inode構造のメモリは事前に割り当てられています)。この戦略は、当時は一般的で直感的で効率的で、DOS、Windows、Linux、その他のオペレーティングシステムで共有されました。
最近では、あなたが見る膨大な数字が理論的最大値(2 64 -1)だと思います。 「実際の」ファイルの最大値は実行時に割り当てられ、ulimit(ulimit -Hn
および)を介してulimit -Sn
設定できます。したがって、「file-max」はulimitの最大値にすぎず、本質的に意味がありません。これは、「何があっても、ulimitにRAMが不足するまで」を意味します。
答え3
ファイル記述子を監視するためにネットワークコードで一般的に使用される関数は、多くの実装select()
で最大1023のファイル記述子のみを処理します。この機能は通常、新しいコードでは廃止されたと見なされますが、この機能を使用するソフトウェアは、より高い番号のファイル記述子を処理すると正しく機能しません。
ファイルディスクリプタはユーザプロセスによってのみ整数値として扱われ、ファイルディスクリプタセットに対する操作は、可能なファイルディスクリプタの小さな固定範囲を想定し、各ファイルディスクリプタが処理対象としてマークされていることを確認する範囲を繰り返すことによって実施される。最大ファイルディスクリプタの数が多すぎると、コストがかかります。