查找当前打开的文件句柄数(不是 lsof)

Posted

技术标签:

【中文标题】查找当前打开的文件句柄数(不是 lsof)【英文标题】:Find current number of open filehandle ( NOT lsof ) 【发布时间】:2011-11-17 07:54:34 【问题描述】:

在 *NIX 系统上,有没有办法找出当前运行的进程中有多少打开的文件句柄?

我正在从正在运行的相关进程中寻找用于 C 语言的 API 或公式。

【问题讨论】:

【参考方案1】:

在某些系统上(见下文),您可以在 /proc/[pid]/fd 中计算它们。如果不是其中之一,请参阅以下内容:wallyk's answer。

c中可以列出目录并统计总数,也可以列出目录内容:

 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>

 int
 main (void)
 
   DIR *dp;
   struct dirent *ep;

   dp = opendir ("/proc/MYPID/fd/");
   if (dp != NULL)
     
       while (ep = readdir (dp))
         puts (ep->d_name);
       (void) closedir (dp);
     
   else
     perror ("Couldn't open the directory");

   return 0;
 

在 bash 中,类似于:

ls -l /proc/[pid]/fd/ | wc -l

支持 proc 文件系统的操作系统包括,但 不限于: 索拉里斯 IRIX Tru64 UNIX BSD Linux(将其扩展到与进程无关的数据) IBM AIX(其实现基于 Linux 以提高兼容性) QNX 贝尔实验室的计划 9

【讨论】:

这不能移植到例如FreeBSD 系统,因为它们没有 /proc/ 文件系统。另外:这并不能回答 OP 的问题。 我喜欢 wallyk 的回答,它更便携,并且依赖于子系统提供的很少的设施。但是,就我而言,我需要确保对文件句柄进行计数的尝试有很高的成功机会;即不必打开和关闭更多文件句柄。从这个意义上说,chown 的解决方案更好,因为它只使用了一个文件句柄。 @CodeMedic:wallyk 解决方案在任何时候都只需要一个额外的文件处理程序,因为它在循环内打开和关闭它。 @salva 虽然,每个 fd 都必须被 dup'd,这可能很好,但 可能 会减慢诸如套接字或跨挂载打开 fd 之类的事情(没有什么可支持的这个声明,它似乎是合理的).. 还有 3.9k 额外的循环运行该方法必须执行(无论如何都可以忽略不计,因为它们只是在 dup 失败时继续)。但对于非 /proc 文件系统,它似乎是最好的选择。【参考方案2】:

想到的适用于任何 *nix 系统的想法是:

int j, n = 0;

// count open file descriptors
for (j = 0;  j < FDMAX;  ++j)     // FDMAX should be retrieved from process limits,
                                  // but a constant value of >=4K should be
                                  // adequate for most systems

    int fd = dup (j);
    if (fd < 0)
        continue;
    ++n;
    close (fd);

printf ("%d file descriptors open\n", n);

【讨论】:

残酷但非常有趣的方法。但它不能区分“真实”文件和其他字符设备,如终端和套接字。 @arne:OP 不要求区分。仅打开文件句柄的总数。 确实是这样,但万一他忘了,我提了。 我喜欢它的简单性;但出于我的目的,我更喜欢 chown 的解决方案。请参阅我的 cmets 以了解原因。 您可以调用 fstat 并检查 EBADF,而不是复制(使用另一个 fd)。【参考方案3】:

OpenSSH 实现了一个closefrom 函数,该函数的作用与您需要混合 wallyk 和 chown 已经提出的两种方法非常相似,而且 OpenSSH 非常可移植,至少在 Unix/Linux/BSD/Cygwin 系统之间是这样。

【讨论】:

【参考方案4】:

没有便携式方法可以获取打开的描述符的数量(无论类型),除非您自己跟踪它们。

【讨论】:

以上是关于查找当前打开的文件句柄数(不是 lsof)的主要内容,如果未能解决你的问题,请参考以下文章

Linux下查看进程打开的文件句柄数

文件句柄统计

Linux下查看进程打开的文件句柄数

修改linux最大文件句柄数

查看linux下进程打开的文件句柄数并清理

如何修改linux单进程能够打开的最大文件句柄数