2021年做可信计算时,由于甲方给的CPU利用率不能不能超过20%;
目的:我们的程序部署甲方服务器上不能阻碍其甲方服务的正常运行
我们的程序在CPU超过20%时,可以休眠几秒后继续运行
此时需要检测控制服务器的CPU资源使用信息,用于做判断程序是否休眠
resource 模块用于测量和控制程序使用的系统资源的基本机制
resource.RLIM_INFINITY
无限资源的限制resource.getrlimit(resource)
当前资源软硬限制的元组(soft, hard)
resource.setrlimit(resource, limits)
设置新的资源消耗限制 limits 两个整数的元组resource.prlimit(pid, resource[, limits])
setrlimit()将和结合getrlimit()在一个函数中,支持获取和设置任意进程的资源限制
如果 pid为0,则调用适用于当前进程
resource和limits与中的含义相同setrlimit(),limits可选
当没有给出限制时,该函数返回进程pid的资源限制
当给定限制时,设置进程的资源限制并返回以前的资源限制
import resource
# 进程可用存储区大小
soft, hard = resource.getrlimit(resource.RLIMIT_AS)
# 进程最大处理器时间
soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
# 设置cpu最大处理时间
resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard))
# 设置进程内存限制,程序运行到没有多余内存时会抛出 MemoryError 异常
resource.setrlimit(resource.RLIMIT_AS, (size, hard))
resource | 解释 | 说明 |
---|---|---|
resource.RLIMIT_AS | 进程可用存储区大小 | |
resource.RLIMIT_CPU | 进程最大处理器时间 | 超出限制SIGXCPU则会向进程发送信号 |
resource.RLIMIT_FSIZE | 进程可创建文件的最大值 | |
resource.RLIMIT_CORE | core文件最大字节 | |
resource.RLIMIT_DATA | 进程堆的最大大小 | 数据段最大长度 |
resource.RLIMIT_MEMLOCK | 可锁定在内存中的最大地址空间 | 使用mlock能否在存储器中锁定最长字节数 |
resource.RLIMIT_NOFILE | 当前进程的最大打开文件数 | |
resource.RLIMIT_NPROC | 当前进程可创建的最大进程数 | |
resource.RLIMIT_RSS | 供给进程的最大驻存集的字节长度 | |
resource.RLIMIT_STACK | 当前进程调用栈的最大长度 | |
resource.RLIMIT_OFILE | - | |
resource.RLIMIT_VMEM | 进程占用的最大映射内存区域 | |
resource.RLIMIT_MSGQUEUE | 分配给POSIX 消息队列的字节数 | |
resource.RLIMIT_NICE | 进程 nice 级别的上限 | |
resource.RLIMIT_RTPRIO | 实时优先级的上限 | |
resource.RLIMIT_RTTIME | 实时优先级的上限 | |
resource.RLIMIT_SIGPENDING | 进程可能排队的信号数 | |
resource.RLIMIT_SBSIZE | 用户使用的套接字缓冲区的最大大小 | |
resource.RLIMIT_SWAP | 该用户 ID 的所有进程保留或使用的交换空间的最大大小 | |
resource.RLIMIT_NPTS | 用户标识创建的伪终端的最大数量 | |
resource.RLIMIT_KQUEUES | 用户 ID 创建的最大 kqueue 数 |
resource.getpagesize() 获取页面大小: 返回系统页面中的字节数
resource.getrusage(who) 由who参数指定的当前进程或其子进程消耗的资源
import resource
# 资源使用状况:请求调用进程消耗的资源,进程中所有线程使用的资源总和
sor = resource.getrusage(resource.RUSAGE_SELF)
# 已终止和等待的调用进程的子进程消耗的请求资源
sor = resource.getrusage(resource.RUSAGE_CHILDREN)
# 当前进程和子进程消耗的资源 并非在所有系统上都可用
sor = resource.getrusage(resource.RUSAGE_BOTH)
# 当前线程消耗的资源 可能并非在所有系统上都可用
sor = resource.getrusage(resource.RUSAGE_THREAD)
# 用户模式下的时间(其它参数如下)
print(sor.ru_utime)
序号 | 函数 | 描述 |
---|---|---|
0 | ru_utime | 用户模式下的时间 |
1 | ru_stime | 系统模式下的时间 |
2 | ru_maxrss | 最大驻留集大小 |
3 | ru_ixrss | 共享内存大小 |
4 | ru_idrss | 非共享堆栈大小 |
5 | ru_isrss | 非共享堆栈大小 |
6 | ru_minflt | 不需要 I/O 的页面错误 |
7 | ru_majflt | 需要 I/O 的页面错误 |
8 | ru_nswap | 换出数量 |
9 | ru_inblock | 块输入操作 |
10 | ru_oublock | 块输出操作 |
11 | ru_msgsnd | 已发送消息 |
12 | ru_msgrcv | 收到的消息 |
13 | ru_nsignals | 收到的信号 |
14 | ru_nvcsw | 自愿上下文切换 |
15 | ru_nivcsw | 非自愿上下文切换 |
官方文档
import signal
import resource
import os
# 限制 CPU 时间
def time_exceeded(signo, frame):
# 超时时打印提示信息并引发 SystemExit 异常,以终止脚本
print("CPU exceeded...")
raise SystemExit(1)
def set_max_runtime(seconds):
# 获取当前 CPU 时间的软限制和硬限制
soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
# 设置软限制为指定的时间,硬限制不变
resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard))
# 安装一个信号处理程序来处理超时信号 SIGXCPU
signal.signal(signal.SIGXCPU, time_exceeded)
# 限制内存使用量
def set_max_memory(size):
# 获取当前内存使用量的软限制和硬限制
soft, hard = resource.getrlimit(resource.RLIMIT_AS)
# 设置软限制为指定的大小,硬限制不变
resource.setrlimit(resource.RLIMIT_AS, (size, hard))
set_max_runtime 函数通过调用 resource 模块中的 getrlimit 和 setrlimit 函数来限制 Python 进程的 CPU 时间。函数首先调用 getrlimit 函数获取当前 CPU 时间的软限制和硬限制,然后将软限制设置为指定的时间,将硬限制保持不变。最后,该函数调用 signal 模块中的 signal 函数,安装一个处理超时信号 SIGXCPU 的信号处理程序,该处理程序在超时时打印一条提示信息并引发 SystemExit 异常以终止脚本。
set_max_memory 函数同样使用 getrlimit 和 setrlimit 函数来限制 Python 进程的内存使用量。该函数首先调用 getrlimit 函数获取当前内存使用量的软限制和硬限制,然后将软限制设置为指定的大小,将硬限制保持不变。