Проверьте лимит открытого FD для данного процесса в Linux - PullRequest
58 голосов
/ 31 августа 2009

Недавно у меня был процесс Linux, который «вытек» из файловых дескрипторов: он открыл их и не закрыл некоторые из них должным образом.

Если бы я следил за этим, я мог бы заранее сказать, что процесс достиг своего предела.

Есть ли хороший способ Bash \ Python проверить коэффициент использования FD для данного процесса в системе Ubuntu Linux?

EDIT:

Теперь я знаю, как проверить, сколько существует дескрипторов открытых файлов; Мне нужно только знать , сколько файловых дескрипторов разрешено для процесса . Некоторые системы (например, Amazon EC2) не имеют файла /proc/pid/limits.

Спасибо

Уди

Ответы [ 7 ]

113 голосов
/ 31 августа 2009

Количество записей в /proc/<pid>/fd/. Жесткие и мягкие ограничения, применимые к процессу, можно найти в /proc/<pid>/limits.

34 голосов
/ 06 сентября 2009

Единственные интерфейсы, предоставляемые ядром Linux для получения лимитов ресурсов: getrlimit() и /proc/ pid /limits. getrlimit() может получить только ограничения на ресурсы вызывающего процесса. /proc/ pid /limits позволяет получить лимиты ресурсов для любого процесса с тем же идентификатором пользователя и доступен в RHEL 5.2, RHEL 4.7, Ubuntu 9.04 и любом дистрибутиве с 2.6.24 или позже ядро.

Если вам требуется поддержка старых систем Linux, вам нужно будет заставить сам процесс вызывать getrlimit(). Конечно, самый простой способ сделать это - изменить программу или библиотеку, которую она использует. Если вы запускаете программу, вы можете использовать LD_PRELOAD для загрузки собственного кода в программу. Если ничего из этого невозможно, вы можете присоединиться к процессу с помощью gdb и заставить его выполнить вызов внутри процесса. Вы также можете сделать то же самое самостоятельно, используя ptrace(), чтобы присоединиться к процессу, вставить вызов в его память и т. Д., Однако это очень сложно сделать правильно и не рекомендуется.

При наличии соответствующих привилегий другие способы сделать это могут включать просмотр памяти ядра, загрузку модуля ядра или другие изменения ядра, но я предполагаю, что об этом не может быть и речи.

2 голосов
/ 21 июня 2013

чтобы увидеть топ-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 для процесса

пример вывода

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
2 голосов
/ 05 сентября 2009

Вы запросили методы bash / python. ulimit был бы лучшим подходом для bash (если не считать, что он прыгает через /proc/$pid/fd и т.п. вручную). Для python вы можете использовать модуль ресурсов.

import resource

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

(1024, 65536)

resource.getrlimit соответствует вызову getrlimit в C-программе. Результаты представляют текущие и максимальные значения для запрашиваемого ресурса. В приведенном выше примере текущее (мягкое) ограничение составляет 1024. В настоящее время значения являются типичными значениями по умолчанию в системах Linux.

2 голосов
/ 31 августа 2009

Вы можете попробовать написать скрипт, который периодически вызывает lsof -p {PID} для данного pid.

0 голосов
/ 18 марта 2018

Оболочка Python с использованием превосходного пакета psutil:

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
0 голосов
/ 29 марта 2017

В CentOS 6 и ниже (все, что использует GCC 3), вы можете обнаружить, что настройка ограничений ядра не решает проблему. Это связано с тем, что существует значение FD_SETSIZE , которое устанавливается во время компиляции и используется GCC. Для этого вам нужно будет увеличить значение, а затем пересобрать процесс.

Кроме того, вы можете обнаружить утечку файловых дескрипторов из-за известных проблем в libpthread , если вы используете эту библиотеку. Этот вызов был интегрирован в GCC в GCC 4 / CentOS7 / RHEL 7, и это, похоже, исправило проблемы с потоками.

...