Чрезвычайно простая программа на Python, занимающая 100% процессорного времени - PullRequest
0 голосов
/ 22 марта 2019

У меня есть эта программа, которая проверяет количество процессоров, используемых текущим процессом Python.

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% моего процессора, и мне трудно понять, почему.Я заметил, что установка time.sleep(0.25) приводит к снижению загрузки ЦП.

В моем реальном приложении у меня есть похожий цикл while, и я не могу позволить себе поспать в цикле while, поскольку он читает видео из OpenCV и должен оставаться в режиме реального времени.

import cv2

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

Эта программа использует такое же количество ЦП, что и первая написанная мной программа, но эта декодирует видео!

Если кто-то может объяснить немного больше,было бы здорово.

Ответы [ 3 ]

1 голос
/ 22 марта 2019

Ваш оригинальный цикл делает что-то так быстро, как только может. Любая программа, которая выполняет работу, связанную исключительно с процессором, без каких-либо значительных операций блокировки, будет с радостью использовать весь процессор, она просто делает все, что делает быстрее, если процессор быстрее.

Ваше конкретное что-то в основном просто увеличивает значение и делит его на 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 циклов быстрее и print cpu_percent чаще (это может немного уменьшает загрузку ЦП, но только потому, что вам может быть print достаточно, чтобы выходной буфер заполнялся быстрее, чем его можно использовать для отображения, и ваша программа могла иногда блокировать ввод-вывод) .

Дело в том, что если вы скажете компьютеру делать что-то всегда так быстро, как он может, это произойдет. Так что не надо. Используйте sleep; даже маленький (time.sleep(0.001)) будет иметь огромное значение.

Для вашего сценария захвата видео кажется, что именно этого вы и хотите. Если источник видео производит достаточно выходных данных, чтобы занять весь ваш процессор, пусть будет так; если это не так, и ваш код блокируется, когда он продвигается, это здорово, но вы не хотите замедлять обработку только ради более низкой загрузки ЦП, если это означает отставание / отбрасывание кадров.

1 голос
/ 22 марта 2019

Возможно, вы захотите добавить time.sleep (numberOfSeconds) к вашему циклу, если не хотите, чтобы он все время использовал 100% CPU, если он только проверяет определенное условие снова и снова.я думаю, что это решит вашу проблему

1 голос
/ 22 марта 2019

Надеюсь, у вас все отлично!

Когда вы делаете:

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

Вы на самом деле просите свой компьютер постоянно обрабатывать.

Он будет увеличивать counter настолько быстро, насколько это возможно, и будет отображать cpu_percent каждый раз, когда counter по модулю 1000.

Это означает, что ваша программа будет загружать процессорпостоянно с инструкциями по увеличению этого счетчика.

Когда вы используете sleep, вы в основном говорите ОС (операционной системе), что ваш код не должен выполнять ничего нового перед временем сна.Ваш код не будет загружать процессор с инструкциями.

Сон приостанавливает выполнение на указанное количество секунд.

В настоящее время лучше использовать режим сна, чем счетчик.

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

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

Надеюсь, это помогает.

Хорошего дня,

G

...