Автор оригинала: Doug Hellmann.
Цель:
Управляйте ограничениями системных ресурсов для программы Unix.
Функции в resource
проверяют текущие системные ресурсы, потребляемые процессом, и устанавливают для них ограничения, чтобы контролировать, какую нагрузку программа может наложить на систему.
Текущее использование
Используйте getrusage ()
, чтобы проверить ресурсы, используемые текущим процессом и/или его дочерними элементами. Возвращаемое значение – это структура данных, содержащая несколько показателей ресурсов в зависимости от текущего состояния системы.
Примечание
Здесь отображаются не все собранные значения ресурсов. Более полный список см. В документации стандартной библиотеки для resource
.
resource_getrusage.py
import resource import time RESOURCES [ ('ru_utime', 'User time'), ('ru_stime', 'System time'), ('ru_maxrss', 'Max. Resident Set Size'), ('ru_ixrss', 'Shared Memory Size'), ('ru_idrss', 'Unshared Memory Size'), ('ru_isrss', 'Stack Size'), ('ru_inblock', 'Block inputs'), ('ru_oublock', 'Block outputs'), ] usage resource.getrusage(resource.RUSAGE_SELF) for name, desc in RESOURCES: print('{:<25} ({:<10}) = {}'.format( desc, name, getattr(usage, name)))
Поскольку тестовая программа чрезвычайно проста, она не использует много ресурсов.
$ python3 resource_getrusage.py User time (ru_utime ) = 0.032299999999999995 System time (ru_stime ) = 0.01517 Max. Resident Set Size (ru_maxrss ) = 9945088 Shared Memory Size (ru_ixrss ) = 0 Unshared Memory Size (ru_idrss ) = 0 Stack Size (ru_isrss ) = 0 Block inputs (ru_inblock) = 0 Block outputs (ru_oublock) = 0
Ограничения ресурсов
Помимо текущего фактического использования, можно проверить ограничения , наложенные на приложение, а затем изменить их.
resource_getrlimit.py
import resource LIMITS [ ('RLIMIT_CORE', 'core file size'), ('RLIMIT_CPU', 'CPU time'), ('RLIMIT_FSIZE', 'file size'), ('RLIMIT_DATA', 'heap size'), ('RLIMIT_STACK', 'stack size'), ('RLIMIT_RSS', 'resident set size'), ('RLIMIT_NPROC', 'number of processes'), ('RLIMIT_NOFILE', 'number of open files'), ('RLIMIT_MEMLOCK', 'lockable memory address'), ] print('Resource limits (soft/hard):') for name, desc in LIMITS: limit_num getattr(resource, name) soft, hard resource.getrlimit(limit_num) print('{:<23} {}/{}'.format(desc, soft, hard))
Возвращаемое значение для каждого ограничения – это кортеж, содержащий мягкий предел, налагаемый текущей конфигурацией, и жесткий предел, установленный операционной системой.
$ python3 resource_getrlimit.py Resource limits (soft/hard): core file size 0/9223372036854775807 CPU time 9223372036854775807/9223372036854775807 file size 9223372036854775807/9223372036854775807 heap size 9223372036854775807/9223372036854775807 stack size 8388608/67104768 resident set size 9223372036854775807/9223372036854775807 number of processes 1418/2128 number of open files 9472/9223372036854775807 lockable memory address 9223372036854775807/9223372036854775807
Пределы можно изменить с помощью setrlimit ()
.
resource_setrlimit_nofile.py
import resource import os soft, hard resource.getrlimit(resource.RLIMIT_NOFILE) print('Soft limit starts as :', soft) resource.setrlimit(resource.RLIMIT_NOFILE, (4, hard)) soft, hard resource.getrlimit(resource.RLIMIT_NOFILE) print('Soft limit changed to :', soft) random open('/dev/random', 'r') print('random has fd =', random.fileno()) try: null open('/dev/null', 'w') except IOError as err: print(err) else: print('null has fd =', null.fileno())
В этом примере RLIMIT_NOFILE
используется для управления допустимым количеством открытых файлов, изменяя его на меньший мягкий предел, чем установленный по умолчанию.
$ python3 resource_setrlimit_nofile.py Soft limit starts as : 9472 Soft limit changed to : 4 random has fd = 3 [Errno 24] Too many open files: '/dev/null'
Также может быть полезно ограничить количество процессорного времени, которое должен потреблять процесс, чтобы не использовать слишком много. Когда процесс проходит отведенное время, он отправляет сигнал SIGXCPU
.
resource_setrlimit_cpu.py
import resource import sys import signal import time # Set up a signal handler to notify us # when we run out of time. def time_expired(n, stack): print('EXPIRED :', time.ctime()) raise SystemExit('(time ran out)') signal.signal(signal.SIGXCPU, time_expired) # Adjust the CPU time limit soft, hard resource.getrlimit(resource.RLIMIT_CPU) print('Soft limit starts as :', soft) resource.setrlimit(resource.RLIMIT_CPU, (1, hard)) soft, hard resource.getrlimit(resource.RLIMIT_CPU) print('Soft limit changed to :', soft) print() # Consume some CPU time in a pointless exercise print('Starting:', time.ctime()) for i in range(200000): for i in range(200000): v i * i # We should never make it this far print('Exiting :', time.ctime())
Обычно обработчик сигнала должен очистить все открытые файлы и закрыть их, но в этом случае он просто печатает сообщение и завершает работу.
$ python3 resource_setrlimit_cpu.py Soft limit starts as : 9223372036854775807 Soft limit changed to : 1 Starting: Sun Mar 18 16:21:52 2018 EXPIRED : Sun Mar 18 16:21:53 2018 (time ran out)
Смотрите также
- Стандартная библиотека документации для ресурса
- signal – Подробнее о регистрации обработчиков сигналов.