我正在通过进程 pid 来计算当前打开的文件:- cmd1:-
ls /proc/$pid/fd/* | wc -l
然后我通过获取最大打开文件限制来计算百分比。 cmd2:-
$ cat /proc/$pid/limits
Limit Soft Limit Hard Limit Units
Max resident set unlimited unlimited bytes
Max processes 30425 30425 processes
Max open files 4096 4096 files
Max locked memory 65536 65536 bytes
仅粘贴部分输出。
我正在计算百分比:-
cmd1/cmd2*100
即如果ls /proc/$pid/fd/* | wc -l
给出 1000。那么百分比将为:- 1000/4096*100= 大约 25%
有时我得到的百分比是 220。
场景现在可以重现,它发生在一台服务器上,我发现
/proc/pid/fd/29
:一个进程打开了 5000 个日志文件。
这意味着进程 pid 超出了最大打开文件限制(4096)。
答案1
请注意,限制是针对新创建的文件描述符的值(如open()
//socket()
等将永远不会返回大于限制设置为 的pipe()
数字,并且将会失败),而不是针对当前打开的文件或文件的数量描述符。n-1
n
dup2(1, n or n+1...)
实际上,从将限制设置为 的那一刻起n
,这将阻止该进程打开多个文件,但如果在降低限制之前已经创建了n
上述文件描述符,则该进程可能会打开多个文件。n
n
例子:
$ limit descriptors 10000 # ulimit -n 10000 in bash
$ perl -MBSD::Resource -MPOSIX -e '
dup2(1,$_) for (2000..4000);
setrlimit(RLIMIT_NOFILE, 1024, 1024);
exec zsh'
zsh$ ls /proc/$$/fd | wc -w
2009
zsh$ readlink /proc/$$/fd/3000
/dev/pts/1
zsh$ repeat 100 exec {a}>&1
zsh$ ls /proc/$$/fd | wc -w
2109
zsh$ grep files /proc/$$/limits
Max open files 1024 1024 files
执行时zsh
,该进程已向 .fds 2000 至 4000 打开/dev/pts/1
。然而 fd 限制是 1024。
它已经有 2009 个 fd,但仍然能够创建 100 个以上。