psutil.Process 和 lsof 命令不一致
psutil.Process and lsof command discrepancy
我编写了一个简单的 Python 脚本来监控 Red Hat 系统上的文件描述符数量。
与 lsof
命令比较时,我得到两个不同的结果。
分解为它的核心,脚本是这样做的:
import psutil
p = psutil.Process(PID)
print(p.num_fds())
目前 num_fds()
报告 60 个打开的文件描述符。
而对于相同的 PID,lsof -p PID | wc -l
的结果会产生 167.
这种差异从何而来?
我的理解是,num_fds()
和 lsof
都报告相同的文件描述符,包括打开的文件句柄、套接字、管道等。
小背景:某些进程似乎打开了套接字and/or 文件句柄而没有再次关闭它们。因此,经过较长时间后,进程达到文件描述符的限制并崩溃。此工具旨在监视此过程是否文件描述符的数量不断增加。
如果你查看 psutil 的源代码,你会发现 num_fds()
只是计算 /proc/<pid>/fd
:
中的“文件”
# _pslinux.py
@wrap_exceptions
def num_fds(self):
return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
和lsof
可能做更多的工作(例如它分析process_proc_map()
中的内存映射):https://github.com/lsof-org/lsof/blob/56d79ed56d14825f234783a867d6bd5676729b32/dialects/linux/dproc.c
查看[=26=中的psutil源码],该方法的实现是:
def num_fds(self):
return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
所以它只是计算 /proc/pid 或等效位置中列出的文件描述符的数量。
查看我当前在 Red Hat 服务器上的进程,pid 目录包含 5 个文件描述符;但是 lsof
报告有 19 个打开的文件。查看完整的 lsof
输出,不同之处在于它列出了似乎与数字文件描述符无关的内容。 lsof
手册页描述:
FD is the File Descriptor number of the file or:
cwd current working directory;
Lnn library references (AIX);
err FD information error (see NAME column);
jld jail directory (FreeBSD);
ltx shared library text (code and data);
Mxx hex memory-mapped type number xx.
m86 DOS Merge mapped file;
mem memory-mapped file;
mmap memory-mapped device;
pd parent directory;
rtd root directory;
tr kernel trace file (OpenBSD);
txt program text (code and data);
v86 VP/ix mapped file;
因此,差异是因为 lsof
包括各种实际上未映射到文件描述符的“打开文件”。
我编写了一个简单的 Python 脚本来监控 Red Hat 系统上的文件描述符数量。
与 lsof
命令比较时,我得到两个不同的结果。
分解为它的核心,脚本是这样做的:
import psutil
p = psutil.Process(PID)
print(p.num_fds())
目前 num_fds()
报告 60 个打开的文件描述符。
而对于相同的 PID,lsof -p PID | wc -l
的结果会产生 167.
这种差异从何而来?
我的理解是,num_fds()
和 lsof
都报告相同的文件描述符,包括打开的文件句柄、套接字、管道等。
小背景:某些进程似乎打开了套接字and/or 文件句柄而没有再次关闭它们。因此,经过较长时间后,进程达到文件描述符的限制并崩溃。此工具旨在监视此过程是否文件描述符的数量不断增加。
如果你查看 psutil 的源代码,你会发现 num_fds()
只是计算 /proc/<pid>/fd
:
# _pslinux.py
@wrap_exceptions
def num_fds(self):
return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
和lsof
可能做更多的工作(例如它分析process_proc_map()
中的内存映射):https://github.com/lsof-org/lsof/blob/56d79ed56d14825f234783a867d6bd5676729b32/dialects/linux/dproc.c
查看[=26=中的psutil源码],该方法的实现是:
def num_fds(self):
return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
所以它只是计算 /proc/pid 或等效位置中列出的文件描述符的数量。
查看我当前在 Red Hat 服务器上的进程,pid 目录包含 5 个文件描述符;但是 lsof
报告有 19 个打开的文件。查看完整的 lsof
输出,不同之处在于它列出了似乎与数字文件描述符无关的内容。 lsof
手册页描述:
FD is the File Descriptor number of the file or:
cwd current working directory;
Lnn library references (AIX);
err FD information error (see NAME column);
jld jail directory (FreeBSD);
ltx shared library text (code and data);
Mxx hex memory-mapped type number xx.
m86 DOS Merge mapped file;
mem memory-mapped file;
mmap memory-mapped device;
pd parent directory;
rtd root directory;
tr kernel trace file (OpenBSD);
txt program text (code and data);
v86 VP/ix mapped file;
因此,差异是因为 lsof
包括各种实际上未映射到文件描述符的“打开文件”。