推荐用psutil.Process.cpu_percent()跨平台获取进程CPU使用率,首次调用返回0.0需预热;用psutil.process_iter()安全按名查多实例进程;kill前须检查状态、捕获异常并先terminate后kill;采样宜设固定间隔与连续阈值判定。

用 psutil 获取进程实时 CPU 使用率
直接读 /proc/[pid]/stat 或调用系统命令(如 top、ps)不仅跨平台差,还难做稳定采样。推荐用 psutil ——它封装了底层差异,支持 Linux/macOS/Windows,且提供 Process.cpu_percent() 这种带时间窗口的准确计算方式。
注意:首次调用 cpu_percent() 总是返回 0.0,必须至少间隔一次再调用才有意义。典型做法是先调一次“预热”,等 0.1–1 秒后再取值:
import psutil p = psutil.Process(pid=1234) p.cpu_percent() # 预热,忽略返回值 time.sleep(0.1) usage = p.cpu_percent() # 这才是真实最近 0.1 秒的占用率
如何可靠地按名字找进程(不止一个 PID)
用名字查进程时,psutil.process_iter() 是唯一安全方式。别用 os.popen('pgrep xxx') ——容易漏掉子进程、匹配到无关路径名,且无权限时直接崩溃。
关键点:
- 加
timeout=1防止卡在僵尸进程或权限拒绝的Process实例上 - 用
p.info['name']而非p.name(),避免重复触发系统调用 - 对多实例场景(比如多个
python3 worker.py),要逐个判断并分别监控
示例逻辑:
for p in psutil.process_iter(['pid', 'name', 'cmdline']):
try:
if 'myapp' in p.info['name'] or 'myapp' in ' '.join(p.info['cmdline']):
check_and_kill_if_high_cpu(p)
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
kill 进程前必须检查状态和权限
直接 p.kill() 很危险:如果进程已退出但残留 Process 对象,会抛 psutil.NoSuchProcess;如果权限不够(比如非 root 杀 system 进程),会抛 psutil.AccessDenied;更糟的是,有些进程收到 SIGTERM 后不退出,得补 SIGKILL。
稳妥做法:
- 调用前先用
p.status()确认不是'zombie'或'dead' - 用
try/except捕获AccessDenied并记录日志,而不是静默失败 - 先
p.terminate(),等 3 秒后仍存活再p.kill()
采样频率和阈值设置的实际影响
CPU 占用是瞬时波动量。设阈值为 90%、每秒采一次,可能频繁误杀;设成 5 秒均值 + 80% 阈值,又可能错过短时打满的恶性循环。
经验参数建议:
- 采样间隔:0.5–2 秒(太短加重系统负担,太长响应滞后)
- 判定依据:连续 3 次超过阈值(比如 85%),比单次触发更稳
- 阈值参考:普通服务建议 75–85%,计算密集型可放宽到 95%,但需同步看内存是否同步飙升
真正容易被忽略的是:同一进程的多次采样之间,cpu_percent() 的时间窗口是累积的。如果你在循环里没控制好 sleep 时长,窗口会漂移,导致数值失真 —— 所以务必用固定间隔 + 显式 sleep,不要依赖循环执行时间。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











