首页 > 解决方案 > pyqt4 / linux /RPi : CPU 使用率缓慢增加到 > 100%

问题描述

我正在构建一个在 Raspberry Pi 上运行并通过串行端口与设备通信的 Python3 / PyQt4 应用程序。

串口在自己的线程中运行。要将消息发送到设备,请使用 Queue()。每一秒,GUI 中的计时器都会将一些消息放入队列中。串行线程一一处理它们,超时和重试,当接收到有效响应时,使用信号/插槽通知 GUI(在主线程中)。

我遇到的问题是 CPU 使用率(由 top 监控)随着时间的推移缓慢增加,最终上升超过 100%(我在一个小时左右后看到大约 150-170%)。串行线程中有一个while(True)循环;增加一点睡眠时间(比如 10-50 毫秒)会降低 CPU 的整体使用率,但最终仍然会发生相同的行为。

奇怪的是,如果我运行应用程序但从不启动计时器(因此不会发生串行通信),CPU 使用率始终保持在 100% 左右。

我试过使用 strace,它告诉我很多时间都花在了 futex 上(30-50%),但我从来没有看到任何东西达到 100% 左右。

编辑: 事实证明,我的问题与串行通信、线程或 QTimer() 几乎无关。我最终发现这是因为我滥用了 GUI 中的对象。我在下面的答案中发布了问题的原因。因此,我还删除了此处的示例代码,这实际上不是原因的一部分。

标签: python-3.xmultithreadingpyqt4raspberry-pi3cpu-usage

解决方案


当我通过剥离代码副本来查找原因的过程中,答案实际上与线程或串行通信无关。

在我的 GUI 中,我有一些简单的对象,它们是 QGraphicsView 的子类并绘制圆圈(实际上它是 LED 的模仿,用于指示好/坏的通信活动)。

当我想改变圆的颜色时,我实际上是在对象中再次调用 drawEllipse()。更糟糕的是,这种情况每秒发生多次。(我最初“模拟”项目时所做的一种令人讨厌的做事方式。)所以治疗是双重的:

  1. 重构代码以每秒仅设置 LED 状态两次(开始查询设备寄存器时一次,完成后一次)

  2. 使用此处记录的正确更改 LED 颜色的方法

通过这些修复,CPU 使用率保持稳定在 40% 左右(并且代码更加简洁)。


推荐阅读