You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何psutil有时会报告当前进程CPU使用率为0.0%?

psutil测量进程CPU使用率出现0.0%的问题分析与解决

问题描述

我尝试使用psutil Python库持续测量当前进程的CPU使用率,脚本计划每1秒输出一次使用率数值,模拟的平均负载较低(约1%),与实际要测量的进程负载类似。但问题在于,psutil有时会报告0.0%的使用率,这在1秒的时间间隔内不符合预期(模拟负载函数中有0.1秒的sleep时间)。

版本信息

  • Python:3.10.8
  • psutil:5.9.0

测试代码

import time
import random
import psutil
import threading

test_time = 10
start_time = time.perf_counter()

def simulate_load():
    while time.perf_counter() - start_time < test_time:
        c = 0
        for _ in range(350):
            c += random.randint(0, 5)
        time.sleep(0.1)

def measure_load():
    log = []
    this_process = psutil.Process()
    this_process.cpu_affinity([15])
    this_process.cpu_percent(interval=0)
    while time.perf_counter() - start_time < test_time:
       log.append(this_process.cpu_percent(interval=0))
       time.sleep(1)
    return log

background_thread = threading.Thread(target=simulate_load)
background_thread.start()

print(measure_load())

输出结果

[0.0, 1.6, 1.5, 0.0, 1.6, 1.5, 0.0, 0.0, 0.0, 3.1]


原因分析与解决方法

核心原因

psutil的cpu_percent(interval=0)是非阻塞式采样,返回的是从上一次调用该方法到当前时刻的CPU使用率。问题出在采样逻辑与负载模拟的时间窗口不匹配:

  1. 负载模拟是间歇性的:每次循环执行短时间计算后sleep 0.1秒,每秒会产生多次短暂的CPU活跃期。
  2. 当cpu_percent(interval=0)的两次采样时间点刚好落在负载线程的sleep阶段时,这段时间内进程无CPU活动,就会返回0.0%。
  3. time.sleep(1)的系统调度误差也可能导致采样窗口错过负载活跃期,进一步放大这种失真。

解决方法

方法1:使用阻塞式采样(推荐)

用cpu_percent(interval=1)替代interval=0+time.sleep(1),让psutil在1秒的阻塞周期内持续采样,能准确捕捉这段时间的平均使用率,避免错过负载活跃窗口:

def measure_load():
    log = []
    this_process = psutil.Process()
    this_process.cpu_affinity([15])
    this_process.cpu_percent(interval=0)  # 初始化基准
    while time.perf_counter() - start_time < test_time:
       # 阻塞1秒并测量这段时间的CPU使用率
       log.append(this_process.cpu_percent(interval=1))
    return log

方法2:高频采样后取平均

如果必须使用非阻塞采样,可缩短采样间隔,每1秒内多次采样后取平均值,覆盖负载的活跃周期:

def measure_load():
    log = []
    this_process = psutil.Process()
    this_process.cpu_affinity([15])
    this_process.cpu_percent(interval=0)
    while time.perf_counter() - start_time < test_time:
        samples = []
        for _ in range(10):
            samples.append(this_process.cpu_percent(interval=0))
            time.sleep(0.1)
        log.append(sum(samples)/len(samples))
    return log

额外说明

  • psutil的cpu_percent计算的是采样间隔内进程占用CPU的时间比例,若采样窗口内进程处于休眠状态,就会返回0.0%。
  • 对于低负载、间歇性活跃的进程,非阻塞式单点采样极易失真,阻塞式或高频平均采样的结果更可靠。

内容的提问来源于stack exchange,提问作者Daniel Whiting

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 19:01:12