文件描述符的数量:/proc/sys/fs/file-nr 和 /proc/$pid/fd 之间有何不同?

文件描述符的数量:/proc/sys/fs/file-nr 和 /proc/$pid/fd 之间有何不同?

我想检查实际使用了多少个文件描述符:

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?我猜它们是由forked 子进程创建的:

man fork

孩子继承副本父级的打开文件描述符集。

man pthreads

POSIX.1 还要求线程分享一系列其他属性(即,这些属性是整个进程的,而不是每个线程的):- 进程 ID

  • 父进程ID

  • 进程组ID和会话ID

  • 控制终端

  • 用户和组 ID

  • 打开文件描述符

答案2

http://www.netadmintools.com/part295.html 一些打开的文件不使用文件描述符:库文件、程序本身(可执行文本)等等,如上所列。这些文件在内核数据结构中的其他地方被记录(例如,cat /proc/PID/maps 可查看库),但它们不使用文件描述符,因此不会耗尽内核的文件描述符最大值。

相关内容