代码之家  ›  专栏  ›  技术社区  ›  Adam Matan

检查Linux中给定进程的打开fd限制

  •  56
  • Adam Matan  · 技术社区  · 16 年前

    我最近有一个Linux进程“泄露”了文件描述符:它打开了它们,但没有正确关闭其中的一些描述符。

    如果我监控了这个过程,我可以提前告诉你这个过程已经达到了极限。

    在UbuntuLinux系统中,有没有一种好的、bash\python的方法来检查给定进程的fd使用率?

    编辑:

    我现在知道如何检查有多少打开的文件描述符;我只需要知道 一个进程允许多少个文件描述符 . 一些系统(如AmazonEC2)没有 /proc/pid/limits 文件。

    谢谢,

    乌迪

    7 回复  |  直到 7 年前
        1
  •  107
  •   caf    12 年前

    统计中的条目 /proc/<pid>/fd/ . 适用于该过程的硬限制和软限制见 /proc/<pid>/limits .

        2
  •  32
  •   mark4o    16 年前

    Linux内核提供的获取资源限制的唯一接口是 getrlimit() /proc/ pid /limits . GeTrimeIt() 只能获取调用进程的资源限制。 /PRO/ PID 极限 允许您获取具有相同用户ID的任何进程的资源限制,并可在RHEL 5.2、RHEL 4.7、Ubuntu 9.04以及具有2.6.24或更高内核的任何分发版上使用。

    如果您需要支持较旧的Linux系统,那么您必须让进程本身调用 GeTrimeIt() . 当然,最简单的方法是修改程序或它使用的库。如果您正在运行该程序,则可以使用 LD_PRELOAD 将您自己的代码加载到程序中。如果这些都不可能,那么可以使用gdb附加到进程,并让它在进程内执行调用。你也可以用同样的方法 ptrace() 要附加到进程,请将调用插入到其内存中,等等,但是要正确执行此操作非常复杂,不建议这样做。

    有了适当的特权,完成这项任务的其他方法将涉及查看内核内存、加载内核模块或修改内核,但我假设这些都是不可能的。

        3
  •  2
  •   Tombart    10 年前

    您可以尝试编写定期调用的脚本 lsof -p {PID} 在给定的PID。

        4
  •  2
  •   Antti Haapala -- Слава Україні    9 年前

    您要求使用bash/python方法。乌利米特是最好的猛击方法 /proc/$pid/fd 就像用手)。对于python,可以使用资源模块。

    import resource
    
    print(resource.getrlimit(resource.RLIMIT_NOFILE))
    
    $ python test.py
    
    (1024, 65536)
    

    resource.getrlimit 对应于 getrlimit 调用C程序。结果表示所请求资源的当前值和最大值。在上面的示例中,当前(软)限制为1024。这些值是目前Linux系统的典型默认值。

        5
  •  1
  •   johnjamesmiller    12 年前

    要使用进程查看前20个文件句柄,请执行以下操作:

    for x in `ps -eF| awk '{ print $2 }'`;do echo `ls /proc/$x/fd 2> /dev/null | wc -l` $x `cat /proc/$x/cmdline 2> /dev/null`;done | sort -n -r | head -n 20
    

    输出格式为文件句柄计数、pid、cmndline for process

    实例输出

    701 1216 /sbin/rsyslogd-n-c5
    169 11835 postgres: spaceuser spaceschema [local] idle
    164 13621 postgres: spaceuser spaceschema [local] idle
    161 13622 postgres: spaceuser spaceschema [local] idle
    161 13618 postgres: spaceuser spaceschema [local] idle
    
        6
  •  0
  •   Community Mohan Dere    8 年前

    在Centos6和更低版本(任何使用GCC 3的版本)中,您可能会发现调整内核限制并不能解决问题。这是因为 FD_SETSIZE 由gcc在编译时设置的值。为此,您需要增加值,然后重新编译流程。

    此外,您可能会发现由于 known issues in libpthread 如果你正在使用那个库。这个调用被集成到GCC4/centos7/rhel 7中的GCC中,这似乎解决了线程问题。

        7
  •  0
  •   Willem    7 年前

    使用优秀psutil包的python包装:

    import psutil
    
    for p in psutil.process_iter(attrs=['pid', 'name', 'username', 'num_fds']):
        try:
            soft, hard = p.rlimit(psutil.RLIMIT_NOFILE)
            cur = p.info['num_fds']
            usage = int(cur / soft * 100)
            print('{:>2d}% {}/{}/{}'.format(
                usage,
                p.info['pid'],
                p.info['username'],
                p.info['name'],
                ))
        except psutil.NoSuchProcess:
            pass