Ответ 1
Подсчитайте записи в /proc/<pid>/fd/
. Твердые и мягкие ограничения, применяемые к процессу, можно найти в /proc/<pid>/limits
.
Недавно у меня был процесс Linux, который "просочился" в дескрипторы файла: он открыл их и не закрыл некоторые из них.
Если бы я контролировал это, я мог бы сказать - заранее - что процесс достиг своего предела.
Есть ли хороший способ Bash\Python проверить коэффициент использования FD для данного процесса в системе Ubuntu Linux?
EDIT:
Теперь я знаю, как проверить, сколько открытых дескрипторов файлов есть; Мне нужно знать , сколько файловых дескрипторов разрешено для процесса. Некоторые системы (например, Amazon EC2) не имеют файла /proc/pid/limits
.
Спасибо,
Уди
Подсчитайте записи в /proc/<pid>/fd/
. Твердые и мягкие ограничения, применяемые к процессу, можно найти в /proc/<pid>/limits
.
Единственными интерфейсами, предоставляемыми ядром 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()
для присоединения к процессу, вставьте вызов в свою память и т.д., Однако это очень сложно сделать правильно и не рекомендуется.
С соответствующими привилегиями другие способы сделать это будут связаны с просмотром памяти ядра, загрузкой модуля ядра или другим модификацией ядра, но я предполагаю, что это не может быть и речи.
Вы можете попытаться написать script, которые периодически вызывают lsof -p {PID}
на заданном pid.
Вы запросили методы bash/python. ulimit был бы лучшим подходом bash (за исключением munging через /proc/$pid/fd
и тому подобное). Для python вы можете использовать ресурсный модуль.
import resource
print(resource.getrlimit(resource.RLIMIT_NOFILE))
$ python test.py (1024, 65536)
resource.getrlimit
соответствует вызову getrlimit
в программе на C. Результаты представляют текущие и максимальные значения для запрашиваемого ресурса. В приведенном выше примере текущий (мягкий) предел равен 1024. В настоящее время значениями являются стандартные значения по умолчанию для систем Linux.
чтобы увидеть дескриптор верхнего дескриптора 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
вывод находится в файле handle count, 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
В CentOS 6 и ниже (что угодно, используя GCC 3), вы можете обнаружить, что настройка ограничений ядра не устраняет проблему. Это связано с тем, что существует значение FD_SETSIZE, установленное во время компиляции, используемое GCC. Для этого вам нужно будет увеличить значение, а затем перекомпилировать процесс.
Кроме того, вы можете обнаружить, что вы пропускаете дескрипторы файлов из-за известных проблем в libpthread, если вы используете эту библиотеку. Этот вызов был интегрирован в GCC в GCC 4/CentOS7/RHEL 7, и это, похоже, устранило проблемы с потоками.