一つのプロセスが開けるファイルの数がリミットより3つ少ないわけ。
以前のエントリ
一つのプロセスが開けるファイルの数はいくつ?(分からずじまい)
で、リミットは2048なのに、アプリケーションから開けるファイルは2045である。という疑問が放置されたままでしたが、なんのことはない、標準入力、標準出力、標準エラーストリームの3つ分が既に確保されてしまっているからなのでした。
で、試しにそれらを閉じてみるプログラムを書いてみる。
#include <stdio.h> void closeTest(int fd); int main() { int a; int retScanf, retFprintf; retScanf = scanf("%d", &a); printf("a = %d(%d)\n", a, retScanf); closeTest(0); retScanf = scanf("%d", &a); printf("a = %d(%d)\n", a, retScanf); /* closeTest(1); */ retFprintf = fprintf(stderr, "error...\n"); printf("retFprintf = %d\n", retFprintf); closeTest(2); retFprintf = fprintf(stderr, "error...\n"); printf("retFprintf = %d\n", retFprintf); closeTest(3); return 0; } void closeTest(int fd) { printf("closing fd %d...\n", fd); int retClose0 = close(fd); printf("close(%d) = %d\n", fd, retClose0); printf("fd %d closed.\n", fd); }
0が標準入力、1が標準出力、2が標準エラーストリームみたいです。
で、0をクローズする前までは、scanfで値が読めていたのに、クローズ後は読めなくなっている。
同様に、2をクローズする前までは、fprintf(stderr, ...)で書けていたのに、クローズ後は書けなくなっています。
ちなみに、標準出力を閉じたら、以降何も出力されずにプログラムが終わったので、異常終了したのかと勘違いしましたが、標準出力を閉じているので、何も出なくなって当然でした(汗
標準出力を閉じないで実行した場合の結果はこんな感じ。
taka@ubuntu:~$ ./a.out 12 a = 12(1) closing fd 0... close(0) = 0 fd 0 closed. a = 12(-1) error... retFprintf = 9 closing fd 2... close(2) = 0 fd 2 closed. retFprintf = -1 closing fd 3... close(3) = -1 fd 3 closed. taka@ubuntu:~$
ところで、標準入力と標準エラーストリームを閉じたら、アプリケーションで開けるファイル数は2つ増えるか?と思い、やってみることに。
まずは、リミットを調べる。
taka@ubuntu:~$ ulimit -n 1024 taka@ubuntu:~$
1プロセス当たり、1024ファイルまで開けることが分かります。
次にプログラム。
#include <stdio.h> int main() { int i; FILE* fp; close(0); close(2); for(i=0; i<3000; i++) { printf("file open %d\n", (i + 1)); fp = fopen(__FILE__, "r"); if(fp == NULL) { puts("file open failed."); break; } } }
これを実行すると、
... file open 1022 file open 1023 file open 1024 file open failed.
となり、1023個までファイルを開けていることになります。
もちろん、close(0); close(2);の2行をコメントアウトすると、
... file open 1020 file open 1021 file open 1022 file open failed.
となります。