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

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

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

【问题讨论】:

    标签: c++ c linux unix setrlimit


    【解决方案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】:

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

      【讨论】:

        猜你喜欢
        • 2013-06-23
        • 2011-03-23
        • 1970-01-01
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-01
        相关资源
        最近更新 更多