检查 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
Check the open FD limit for a given process in Linux
提问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/limits
file.
我现在知道如何检查有多少打开的文件描述符;我只需要知道一个进程允许使用多少个文件描述符。某些系统(如 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/fd
and 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.getrlimit
corresponds to the getrlimit
call 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/limits
allows 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/limits
。 getrlimit()
只能获取调用进程的资源限制。 /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_PRELOAD
to 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