ファイルディスクリプタ(File descriptor)は、日本語ではファイル記述子とも呼ばれるようです。
プログラミングの世界では、単にFDと省略されることもあります。
ファイルディスプリプタって何なんでしょうか?
ファイルディスクリプタとは?仕組みと枯渇、解放
ファイルディスクリプタとは、0から始まる整数の識別子です。
ファイルディスクリプタとは、プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子。0から順番に整数の値が割り当てられる。OSによってはファイルディスクリプタにバッファ管理機能なども含めた「ファイルハンドル」と呼ばれる管理体系が存在する。
ファイルディスクリプタには、識別子とともにファイル名、ファイルサイズ、プログラムが操作中のファイル内の位置、ファイル作成、更新日時などの情報が含まれており、OSは識別子によってどのファイルを操作するかを判断する。
通常、0:標準入力(stdin)、1:標準出力(stdout)、2:標準エラー出力(stderr)の3つはOS(シェル)が最初に用意するため、プログラムがファイルをオープンすると「3」から順番にディスクリプタが割り当てられる。
http://e-words.jp/w/ファイルディスクリプタ.html
0 = stdin
1 = stdout
2 = stderr
というのは大事なので覚えておきましょう。
以下の記事にもまとめています。
プログラムがファイルをオープンすると「3」から順番にディスクリプタが増えて割り当てられます。
一つのプロセスがファイルオープン可能な上限を超えて、ファイルディスクリプタが枯渇した場合、エラーが出てそれ以上はオープンできなくなります。
よって、プロセス内でファイルディスクリプタが不要になった場合は、解放漏れがないように制御する必要があります。
Visual Studioでは、stdio.hで以下のように定義されているらしい。
1 2 3 |
int _fileno( FILE *stream ); |
MSDNに以下のサンプルプログラムが載っていました。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// crt_fileno.c // This program uses _fileno to obtain // the file descriptor for some standard C streams. // #include <stdio.h> int main( void ) { printf( "The file descriptor for stdin is %d\n", _fileno( stdin ) ); printf( "The file descriptor for stdout is %d\n", _fileno( stdout ) ); printf( "The file descriptor for stderr is %d\n", _fileno( stderr ) ); } |
実行結果は次の通りです。
The file descriptor for stdin is 0
The file descriptor for stdout is 1
The file descriptor for stderr is 2
Windowsのファイルディスクリプタ(ファイルハンドル)とC言語、上限
Microsoft Windowsの世界ではファイルディスクリプタは、ファイルハンドルと呼ばれることがあります。
Windowsでは、1プロセスあたり255*255*255=16581375個のハンドルが上限です。
ただ、Visual Studioなどを使ってC言語のライブラリ関数を使うと、ライブラリの仕様により上限が変わるようです。
16581375個のファイルがオープンできる訳ではありません。
マイクロソフトのMSDNの公式ドキュメントには以下のように記述されていました。
C ランタイム ライブラリには、同時に開くことのできるファイル数の上限が 512 に設定されています。 上限を超える数のファイル記述子またはファイル ストリームを開こうとすると、プログラム エラーが発生します。
上限のファイル数を変更するには、_setmaxstdio を使用します。
上限を超える、多くのファイルをオープンすると「Too Many Open Files」のような警告が出るようです。
Linuxのファイルディスクリプタの上限、確認
Linuxの場合、ファイルディスクリプタの上限の確認は、ulimit コマンドを使って行います。
1 2 |
$ ulimit -n 1024 |
ulimit -n を使って、一時的に制限を変更することが可能です。
ただし、システムを再起動すると元に戻ってしまいます。
よって、永続的に制限を変更するには、
/etc/security/limits.conf の設定を書き変え、制限を変更するようにします。
全てのユーザー(*)のプロセスが使えるファイルディスクリプタ(nofile)のsoft(ユーザーが設定できる)とhard(rootが設定できる)上限を共に64000にするには、以下のように設定します。
/etc/security/limits.conf
1 2 |
* soft nofile 64000 * hard nofile 64000 |
ちなみに、Linuxでファイルディスクリプタの上限を超えて一つのプロセス内で多くのファイルオープンをすると、次のようなエラーが起きます。
cannot make pipe for process substitution: Too many open files
コメント