最大文件描述符

最大文件描述符

我希望编写一个脚本来使用我的 Linux 机器上的所有可用文件描述符。我不确定到底如何做到这一点,或者是否可能?但我希望在我的 Linux 虚拟机上使用这个脚本进行“混沌猴子”类型的实验。

我更喜欢脚本在 bash 中,但我对此并不太挑剔。

答案1

这将完成(在我的系统上大约需要 40 秒):

#!/bin/bash
[ "$BASHPID" = "$$" ] || { echo "Must run in a new process group"; exit 1; }>&2
cnt0() { cnt0=$#; }
cnt1() { cnt1=$#; }

tmpd=
trap 'rm -rf "$tmpd"; exit 1' INT HUP QUIT EXIT
tmpd=$(mktemp -d)
mkfifo "$tmpd/fifo"
exec 4<>"$tmpd/fifo"
rm -rf "$tmpd"
trap - INT HUP QUIT EXIT


open_all()
{ 
    cnt0 /proc/self/fd/*; 
    while exec {fd}</dev/null; do :; done; 
    cnt1 /proc/self/fd/*;
    nopened=$((cnt1-cnt0));
    echo $nopened >&4;
    cat /proc/sys/fs/file-nr
    if ((nopened)); then
        sleep 10000000
    fi
}

( open_all )&
while :; do
    if read nopened <&4 && ((nopened)); then
        ( open_all )&
        continue
    fi
    break
done
kill -TERM -$$

它的工作原理是在子 shell 中打开/dev/null尽可能多的次数(根据您的情况,它应该工作大约 1000-4000 次ulimit -n)。如果至少打开了一个文件描述符,则会通过管道通知父级,并使用 挂起子 shell sleep。父进程通过在另一个子 shell 中继续该进程直到一个子 shell 失败来响应子进程中成功的 fd 分配。

/proc/sys/fs/file-nr每次迭代都会cat显示 ted,让您了解该过程如何继续。

在该过程结束时,您应该得到类似以下内容的信息:

...
778192  0       786806
779248  0       786806
780272  0       786806
781264  0       786806
782256  0       786806
783280  0       786806
784304  0       786806
785328  0       786806
786352  0       786806
./open_all: line 35: cannot redirect standard input from /dev/null: Too many open files in system
./open_all: line 18: fd: Too many open files in system
Terminated

我从中学到的一件有趣的事情是,重复的文件描述符(来自 dup 或 fork)不计入限制(从具有许多文件描述符的父进程生成进程不会增加计数)。

答案2

while true ; do cat > $(( $RANDOM * $RANDOM )).file & done; 如果不是 root,您可能会达到最大进程限制。如果是这样,请使用一个 perl 进程来打开文件。您可以使用 sysctl 降低 maxfiles,尽管我不知道该变量。

相关内容