【问题标题】:Extremely simple Python program taking up 100% of CPU非常简单的Python程序占用100%的CPU
【发布时间】:2019-03-22 19:06:44
【问题描述】:

我有这个程序可以检查当前 Python 进程使用的 CPU 量。

import os
import psutil

p = psutil.Process(os.getpid())

counter = 0
while True:
    if counter % 1000 == 0:
        print(p.cpu_percent())
    counter += 1

输出是:

98.79987719751766
98.79981257674615
98.79975442677997
98.80031017770553
98.80022615662917
98.80020675841527
98.80027781367056
98.80038116157328
98.80055555555509
98.80054906013777
98.8006523704943
98.80072337402265
98.80081374321833
98.80092993219198
98.80030995738038
98.79962549234794
98.79963842975158
98.79916715088079
98.79930277598402
98.7993480085206
98.79921895171654
98.799154456851

从输出中可以看出,这个程序占用了我 100% 的 CPU,我很难理解原因。我注意到放置 time.sleep(0.25) 会导致 CPU 使用率降至零。

在我的实际应用程序中,我有一个类似的 while 循环,并且不能在 while 循环中休眠,因为它正在从 OpenCV 读取视频并且需要保持实时。

import cv2

cap = cv2.VideoCapture("video.mp4")
while True:
    success, frame = cap.retrieve()

这个程序和我写的第一个程序一样占用相同的 CPU,但是这个程序解码视频!

如果有人能解释更多,那就太棒了。

【问题讨论】:

  • 为什么在一个紧凑的循环中捕获视频帧会占用您所有可用的 CPU 时间?您正在反复指示您的计算机执行大量工作。
  • 不,OP 正在比较 CPU 检查程序 捕获视频帧的程序
  • 至于你的第一个程序,如果你不在那里放一个sleep,那么你使用counter 并不重要。您的计算机可以非常快地数到 1000,并且也会使用一些 CPU。

标签: python python-3.x opencv cv2


【解决方案1】:

我希望你做得很好!

当你这样做时:

while True:
if counter % 1000 == 0:
    print(p.cpu_percent())
counter += 1

您实际上要求您的计算机不断处理。

它将尽可能快地增加counter,并在每次counter 以1000 为模时显示cpu_percent

这意味着您的程序将不断向 CPU 提供递增计数器的指令。

当您使用睡眠时,您基本上是对操作系统(操作系统)说,您的代码不应该在睡眠时间之前执行任何新的操作。然后,您的代码将不会向 CPU 发送指令。

Sleep 在给定的秒数内暂停执行。

目前最好使用睡眠而不是计数器。

import os
import psutil
import time
p = psutil.Process(os.getpid())

counter = 0
while True:
    time.sleep(1)
    print(p.cpu_percent())

我希望它会有所帮助。

祝你有美好的一天,

G

【讨论】:

    【解决方案2】:

    您的原始循环正在尽可能快地完成某事。任何执行纯粹受 CPU 限制的工作的程序,不涉及重大阻塞操作,都会愉快地消耗整个 CPU,如果 CPU 更快,它只会做它正在做的更快的事情。

    您的特定事物主要只是增加一个值并将其除以 1000 一遍又一遍,这是低效的,但会提高效率,例如通过将循环更改为:

    import os
    import psutil
    
    p = psutil.Process(os.getpid())
    
    while True:
        for i in range(1000): pass
        print(p.cpu_percent())
    

    删除所有除法工作并进行更有效的添加(range 在 C 层完成工作),这仅意味着您可以更快地执行 1000 次循环,printcpu_percent 更频繁(它可能 略微降低 CPU 使用率,但这仅仅是因为您可能已经printing 足够了,以至于输出缓冲区的填充速度比显示时耗尽的速度快,并且您的程序可能偶尔会阻塞 I/O )。

    关键是,如果你告诉计算机永远尽可能快地做某事,它会的。所以不要。使用sleep;即使是很小的 (time.sleep(0.001)) 也会产生巨大的影响。

    对于您的视频捕获场景,这似乎就是您想要的。如果视频源产生的输出足以占用你的整个 CPU,那就这样吧;如果不是这样,并且您的代码在超前时会阻塞,那很好,但是如果这意味着落后/丢帧,您不想仅仅为了降低 CPU 使用率而减慢处理速度。

    【讨论】:

      【解决方案3】:

      如果您不希望循环一直使用 100% 的 CPU,如果它只是一遍又一遍地检查某个条件,您可能需要在循环中添加 time.sleep(numberOfSeconds)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-10
        • 2016-03-22
        • 2016-05-17
        • 2020-03-22
        • 1970-01-01
        • 2011-11-09
        • 1970-01-01
        • 2012-12-29
        相关资源
        最近更新 更多