我想检查实际使用了多少个文件描述符:
cat /proc/sys/fs/file-nr
12750 0 753795
第一列(12750)表示自启动以来分配的文件描述符的数量。
我想知道为什么以下命令中的数字不同(假设这一行返回正确的值:
for pid in $(lsof | awk '{ print $2 }' | uniq); do find /proc/$pid/fd/ -type l 2>&1 | grep -v "No"; done | wc -l
11069
答案1
lsof
仅列出过程ID。要获取有关线程的信息,您应该使用ps -eLf
。根据man proc
:
/proc/[pid]/任务(自 Linux 2.6.0-test6 起) 这是一个包含每个子目录的目录 进程中的线程。每个子目录的名称是 数字线程 ID([时间])的线程(见获取ID(2))。 在每个子目录中,都有一组文件 名称和内容与/proc/[pid] 目录。对于所有线程共享的属性, 每个文件的内容任务/[tid] 子目录将与相应文件相同 在父级中/proc/[pid]目录(例如,在多线程中 过程中,所有的任务/[tid]/cwd文件将具有相同的 价值作为/proc/[pid]/cwd父目录中的文件, 由于进程中的所有线程共享一个工作 目录)。对于每个线程不同的属性, 对应的文件如下任务/[tid]可能有所不同 值(例如,每个任务/[tid]/状态 每个线程的文件可能不同)。
在多线程进程中, /proc/[pid]/任务如果主 线程已经终止(通常通过调用 pthread_exit(3))。
我将通过运行以下命令来计算打开的文件描述符的数量:
ps -eL | awk 'NR > 1 { print $1, $2 }' | \
while read x; do \
find /proc/${x% *}/task/${x#* }/fd/ -type l; \
done | wc -l
结果为 17270。
让我们看看自启动以来分配了多少个文件描述符:
cat /proc/sys/fs/file-nr
11616 0 398855
/proc/[pid]/task/[tid]/fd
为什么中的文件描述符数量比中分配的文件句柄数量多/proc/sys/fs/file-nr
?我猜它们是由fork
ed 子进程创建的:
孩子继承副本父级的打开文件描述符集。
POSIX.1 还要求线程分享一系列其他属性(即,这些属性是整个进程的,而不是每个线程的):- 进程 ID
父进程ID
进程组ID和会话ID
控制终端
用户和组 ID
打开文件描述符
答案2
http://www.netadmintools.com/part295.html 一些打开的文件不使用文件描述符:库文件、程序本身(可执行文本)等等,如上所列。这些文件在内核数据结构中的其他地方被记录(例如,cat /proc/PID/maps 可查看库),但它们不使用文件描述符,因此不会耗尽内核的文件描述符最大值。