18.6. resource — 系统资源管理
目的:管理 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'
限制进程应消耗的 CPU 时间量也很有用,以避免使用太多。 当进程超过规定的时间时,它发送了一个 SIGXCPU
信号。
resource_setrlimit_cpu.py
import resource
import sys
import signal
import time
# 设置一个信号处理程序,
# 以便在我们用完时通知我们。
def time_expired(n, stack):
print('EXPIRED :', time.ctime())
raise SystemExit('(time ran out)')
signal.signal(signal.SIGXCPU, time_expired)
# 调整 CPU 时间限制
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()
# 在毫无意义的活动中消耗一些 CPU 时间
print('Starting:', time.ctime())
for i in range(200000):
for i in range(200000):
v = i * i
# 我们永远不应该做到这一点
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)
另请参阅
- resource 标准库文档
signal
-- 有关注册信号处理程序的详细信息。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。