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)

另请参阅

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/pymotw/resource...

译文地址:https://learnku.com/docs/pymotw/resource...

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~