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

如何用Python获取与任务管理器一致的CPU使用率?

问题原因及解决方案

你的代码存在两个关键问题,导致psutil获取的CPU使用率和任务管理器数据不符:

1. 阻塞式调用打乱统计逻辑与Qt事件循环

你在update_value中每次调用psutil.cpu_percent(interval=1),这会阻塞当前线程1秒来计算这段时间的CPU使用率。而Qt定时器设置为每1秒触发一次更新,这就导致:

  • 每次更新操作实际占用1秒阻塞时间,定时器下一次触发被延迟,实际更新间隔变成2秒左右
  • 阻塞期间Qt界面无法响应其他事件,不仅会卡顿,还会导致CPU使用率的统计窗口和任务管理器的统计周期不匹配

2. 重复初始化基线的逻辑冗余

你在第一次调用时执行psutil.cpu_percent(interval=1)建立基线,紧接着又调用一次同样带interval=1的方法,两次调用间隔几乎为0,第二次统计的是第一次结束后1秒的使用率,完全浪费了一次阻塞时间。


修复后的代码

解决思路是使用非阻塞式的CPU使用率获取方式:第一次调用初始化基线,之后每次调用直接获取从上一次到当前的使用率,避免阻塞Qt主线程。

import sys
import psutil  # 获取CPU和内存使用率
from PyQt5 import QtWidgets, QtCore, QtGui

class CircularProgressBar(QtWidgets.QWidget):
    def __init__(self, label="CPU", color=QtGui.QColor(255, 140, 0), parent=None):
        super().__init__(parent)
        self.label = label
        self.color = color
        self.value = 0
        # 初始化CPU使用率基线,非阻塞
        psutil.cpu_percent(interval=0)
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_value)
        self.timer.start(1000)  # 每1秒更新一次

    def update_value(self):
        # 非阻塞获取从上一次调用到现在的CPU使用率
        self.value = psutil.cpu_percent(interval=0)
        self.update()

    def paintEvent(self, event):
        width = self.width()
        height = self.height()
        side = min(width, height)

        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        # 绘制背景圆
        rect = QtCore.QRectF(10, 10, side - 20, side - 20)
        pen = QtGui.QPen(QtCore.Qt.gray, 10)
        painter.setPen(pen)
        painter.drawArc(rect, 0, 360 * 16)

        # 绘制进度弧
        pen.setColor(self.color)
        painter.setPen(pen)
        angle = int(self.value * 360 / 100) * 16
        painter.drawArc(rect, 90 * 16, -angle)

        # 绘制标签和百分比
        painter.setPen(QtCore.Qt.white)
        painter.setFont(QtGui.QFont("Arial", side // 10))
        painter.drawText(rect, QtCore.Qt.AlignCenter, f"{self.label}\n{self.value:.0f}%")

        painter.end()

def main():
    app = QtWidgets.QApplication(sys.argv)
    window = QtWidgets.QMainWindow()
    window.setWindowTitle("资源监视器")

    central_widget = QtWidgets.QWidget()
    layout = QtWidgets.QHBoxLayout(central_widget)

    cpu_bar = CircularProgressBar("CPU", QtGui.QColor(255, 140, 0))
    cpu_bar.setMinimumSize(200, 200)
    
    layout.addWidget(cpu_bar)
    window.setCentralWidget(central_widget)

    window.resize(600, 400)
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

额外说明

  • psutil.cpu_percent(interval=0):立即返回从上一次调用该方法到当前的平均CPU使用率,不会阻塞线程
  • 初始化时调用一次psutil.cpu_percent(interval=0)是为了建立统计基线,避免第一次获取到0值
  • 修复后不仅CPU使用率的数值会和任务管理器一致,界面也不会再出现卡顿现象

内容的提问来源于stack exchange,提问作者Joan Venge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 13:26:05