检查 Linux 中给定进程的开放 FD 限制

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1356675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:39:50  来源:igfitidea点击:

Check the open FD limit for a given process in Linux

linuxscriptingoperating-systemlimitfile-descriptor

提问by Adam Matan

I recently had a Linux process which "leaked" file descriptors: It opened them and didn't properly close some of them.

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

If I had monitored this, I could tell - in advance - that the process was reaching its limit.

如果我对此进行了监控,我可以提前知道该过程已达到极限。

Is there a nice, Bash\Python way to check the FD usage ratio for a given process in a Ubuntu Linux system?

是否有一种不错的 Bash\Python 方法来检查 Ubuntu Linux 系统中给定进程的 FD 使用率?

EDIT:

编辑:

I now know how to check how many open file descriptors are there; I only need to know how many file descriptors are allowed for a process. Some systems (like Amazon EC2) don't have the /proc/pid/limitsfile.

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

Thanks,

谢谢,

Udi

乌迪

采纳答案by caf

Count the entries in /proc/<pid>/fd/. The hard and soft limits applying to the process can be found in /proc/<pid>/limits.

计算 中的条目/proc/<pid>/fd/。适用于该过程的硬限制和软限制可以在 中找到/proc/<pid>/limits

回答by Victor Sorokin

You can try to write script which periodically call lsof -p {PID}on given pid.

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

回答by bwalton

You asked for bash/python methods. ulimit would be the best bash approach (short of munging through /proc/$pid/fdand the like by hand). For python, you could use the resource module.

您要求使用 bash/python 方法。ulimit 将是最好的 bash 方法(没有手动完成/proc/$pid/fd等)。对于python,您可以使用资源模块。

import resource

print(resource.getrlimit(resource.RLIMIT_NOFILE))
$ python test.py

(1024, 65536)
$ python test.py

(1024, 65536)

resource.getrlimitcorresponds to the getrlimitcall in a C program. The results represent the current and maximum values for the requested resource. In the above example, the current (soft) limit is 1024. The values are typical defaults on Linux systems these days.

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

回答by mark4o

The only interfaces provided by the Linux kernel to get resource limits are getrlimit()and /proc/pid/limits. getrlimit()can only get resource limits of the calling process. /proc/pid/limitsallows you to get the resource limits of any process with the same user id, and is available on RHEL 5.2, RHEL 4.7, Ubuntu 9.04, and any distribution with a 2.6.24 or later kernel.

Linux 内核提供的获取资源限制的唯一接口是getrlimit()/proc/pid/limitsgetrlimit()只能获取调用进程的资源限制。 /proc/pid/limits允许您获取具有相同用户 ID 的任何进程的资源限制,并且可用于 RHEL 5.2、RHEL 4.7、Ubuntu 9.04 和任何具有 2.6.24 或更高版本内核的发行版。

If you need to support older Linux systems then you will have to get the process itself to call getrlimit(). Of course the easiest way to do that is by modifying the program, or a library that it uses. If you are running the program then you could use LD_PRELOADto load your own code into the program. If none of those are possible then you could attach to the process with gdb and have it execute the call within the process. You could also do the same thing yourself using ptrace()to attach to the process, insert the call in its memory, etc., however this is very complicated to get right and is not recommended.

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

With appropriate privileges, the other ways to do this would involve looking through kernel memory, loading a kernel module, or otherwise modifying the kernel, but I am assuming that these are out of the question.

使用适当的权限,执行此操作的其他方法将涉及查看内核内存、加载内核模块或以其他方式修改内核,但我假设这些都是不可能的。

回答by johnjamesmiller

to see the top 20 file handle using processes:

使用进程查看前 20 个文件句柄:

for x in `ps -eF| awk '{ print  }'`;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

the output is in the format file handle count, pid, cmndline for process

输出格式为 file handle count, pid, cmndline for process

example output

示例输出

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

回答by James Shewey

In CentOS 6 and below (anything using GCC 3), you may find that adjusting the kernel limits does not resolve the issue. This is because there is a FD_SETSIZEvalue that is set at compile time in use by GCC. For this, you will need to increase the value and then re-compile the process.

在 CentOS 6 及以下(任何使用 GCC 3 的系统)中,您可能会发现调整内核限制并不能解决问题。这是因为GCC 在编译时设置了一个FD_SETSIZE值。为此,您需要增加该值,然后重新编译该过程。

Also, you may find that you are leaking file descriptors due to known issues in libpthreadif you are using that library. This call was integrated into GCC in GCC 4 / CentOS7 / RHEL 7 and this seems to have fixed the threading issues.

此外,如果您正在使用该库,您可能会发现由于libpthread 中的已知问题,您正在泄漏文件描述符。此调用已集成到 GCC 4 / CentOS7 / RHEL 7 中的 GCC 中,这似乎解决了线程问题。

回答by Willem

Python wrapper using the excellent psutil package:

使用优秀的 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