Как получить использование процессора в Python 2.7 без использования PSUtil - PullRequest
0 голосов
/ 31 января 2019

Попытка получить загрузку ЦП в Python без использования PSUtil.

Я пробовал следующее, но всегда кажется, что сообщается одно и то же число ...

def getCPUuse():
    return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip(\
)))

print(getCPUuse())

Похоже, что он всегда показывает 3,7%, даже когда я загружаю процессор.

Я также пробовал следующее ...

str(round(float(os.popen('''grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage }' ''').readline()),2))

Кажется, всегда возвращается 5.12.Должен признать, я действительно не знаю, что делает вышеперечисленное.Если я введу grep cpu /proc/stat в командную строку, я получу что-то вроде этого ...

cpu  74429 1 19596 1704779 5567 0 284 0 0 0
cpu0 19596 0 4965 422508 1640 0 279 0 0 0
cpu1 18564 1 4793 427115 1420 0 1 0 0 0
cpu2 19020 0 4861 426916 1206 0 2 0 0 0
cpu3 17249 0 4977 428240 1301 0 2 0 0 0

Я предполагаю, что моя команда неправильно извлекает значения для всех моих ядер ЦП из вышеприведенного вывода?

Моя цель - получить общий процент CPU от моего устройства (Raspberry PI) без использования PSUtil.Рисунок должен отражать то, что отображается в диспетчере задач ОС.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Что PSUtil, htop, mpstat и т. П. Читает строку, начинающуюся с "cpu" (на самом деле первая строка) из /proc/stat, а затем вычисляет процент от значений в этой строке.Вы можете найти значение значений в этой строке в man 5 proc (поиск «proc / stat»).

Это также то, что делает упомянутая вами команда grep cpu /proc/stat | awk .....Но значения в /proc/stat представляют время, проведенное с момента последней загрузки!Может быть, через некоторое время они обернутся, я не уверен, но дело в том, что это числа, измеренные за очень долгое время.

Так что, если вы выполните эту команду, и выполните ее снова через несколько секунд (, минут или даже часов) спустя, они не сильно изменились!Вот почему вы видели, что он всегда возвращает 5.12.

Такие программы, как top, запоминают предыдущие значения и вычитают их из вновь прочитанных значений.Из этого результата можно рассчитать «живой» процент, который фактически отражает недавнюю загрузку процессора.

Чтобы сделать что-то подобное в Python как можно проще, но без выполнения внешних команд для чтения /proc/stat и выполнения вычисленийдля нас мы можем сохранить значения, которые мы прочитали, в файл.При следующем запуске мы можем прочитать их обратно и вычесть их из новых значений.

#!/usr/bin/env python2.7

import os.path

# Read first line from /proc/stat. It should start with "cpu"
# and contains times spent in various modes by all CPU's totalled.
#
with open("/proc/stat") as procfile:
    cpustats = procfile.readline().split()

# Sanity check
#
if cpustats[0] != 'cpu':
    raise ValueError("First line of /proc/stat not recognised")

#
# Refer to "man 5 proc" (search for /proc/stat) for information
# about which field means what.
#
# Here we do calculation as simple as possible:
# CPU% = 100 * time_doing_things / (time_doing_things + time_doing_nothing)
#

user_time = int(cpustats[1])    # time spent in user space
nice_time = int(cpustats[2])    # 'nice' time spent in user space
system_time = int(cpustats[3])  # time spent in kernel space

idle_time = int(cpustats[4])    # time spent idly
iowait_time = int(cpustats[5])    # time spent waiting is also doing nothing

time_doing_things = user_time + nice_time + system_time
time_doing_nothing = idle_time + iowait_time

# The times read from /proc/stat are total times, i.e. *all* times spent
# doing things and doing nothing since last boot.
#
# So to calculate  meaningful CPU % we need to know how much these values
# have *changed*.  So we store them in a file which we read next time the
# script is run.
# 
previous_values_file = "/tmp/prev.cpu"
prev_time_doing_things = 0
prev_time_doing_nothing = 0

try:
    with open(previous_values_file) as prev_file:
        prev1, prev2 = prev_file.readline().split()
    prev_time_doing_things = int(prev1)
    prev_time_doing_nothing = int(prev2)
except IOError:  # To prevent error/exception if file does not exist. We don't care.
    pass   

# Write the new values to the file to use next run
#
with open(previous_values_file, 'w') as prev_file:
    prev_file.write("{} {}\n".format(time_doing_things, time_doing_nothing))

# Calculate difference, i.e: how much the number have changed
#
diff_time_doing_things = time_doing_things - prev_time_doing_things
diff_time_doing_nothing = time_doing_nothing - prev_time_doing_nothing

# Calculate a percentage of change since last run:
#
cpu_percentage = 100.0 * diff_time_doing_things/ (diff_time_doing_things + diff_time_doing_nothing)

# Finally, output the result
#
print "CPU", cpu_percentage, "%"

Вот версия, которая, в отличие от top, печатает использование ЦП каждую секунду, вспоминая время ЦП из предыдущего измерения.в переменных вместо файла:

#!/usr/bin/env python2.7

import os.path
import time

def get_cpu_times():
    # Read first line from /proc/stat. It should start with "cpu"
    # and contains times spend in various modes by all CPU's totalled.
    #
    with open("/proc/stat") as procfile:
        cpustats = procfile.readline().split()

    # Sanity check
    #
    if cpustats[0] != 'cpu':
        raise ValueError("First line of /proc/stat not recognised")

    # Refer to "man 5 proc" (search for /proc/stat) for information
    # about which field means what.
    #
    # Here we do calculation as simple as possible:
    #
    # CPU% = 100 * time-doing-things / (time_doing_things + time_doing_nothing)
    #

    user_time = int(cpustats[1])    # time spent in user space
    nice_time = int(cpustats[2])    # 'nice' time spent in user space
    system_time = int(cpustats[3])  # time spent in kernel space

    idle_time = int(cpustats[4])    # time spent idly
    iowait_time = int(cpustats[5])    # time spent waiting is also doing nothing

    time_doing_things = user_time + nice_time + system_time
    time_doing_nothing = idle_time + iowait_time

    return time_doing_things, time_doing_nothing


def cpu_percentage_loop():
    prev_time_doing_things = 0
    prev_time_doing_nothing = 0
    while True:  # loop forever printing CPU usage percentage
        time_doing_things, time_doing_nothing = get_cpu_times()
        diff_time_doing_things = time_doing_things - prev_time_doing_things
        diff_time_doing_nothing = time_doing_nothing - prev_time_doing_nothing
        cpu_percentage = 100.0 * diff_time_doing_things/ (diff_time_doing_things + diff_time_doing_nothing)

        # remember current values to subtract next iteration of the loop
        #
        prev_time_doing_things = time_doing_things
        prev_time_doing_nothing = time_doing_nothing

        # Output latest perccentage
        #
        print "CPU", cpu_percentage, "%"

        # Loop delay
        #
        time.sleep(1)

if __name__ == "__main__":
    cpu_percentage_loop()
0 голосов
/ 31 января 2019

Это не очень просто, так как большая часть описываемого вами процесса обеспечивает совокупное или общее среднее использование ЦП.

Может быть, вы можете попробовать использовать команду mpstat, которая идет с te systat package.

Итак, шаги, которые я использовал для следующего скрипта:

  1. Попросите mpstat сгенерировать 2 отчета, один прямо сейчас, а другой через 1 секунду (mpstat 1 2)
  2. Затем мы получаем строку Average (последняя строка)
  3. Последний столбец - это столбец %idle, поэтому мы получаем его с помощью переменной $NF из awk
  4. Мы используем Popen из подпроцесса, но устанавливаем shell=True, чтобы принять параметры наших каналов (|).
  5. Мы выполняем команду (communicate())
  6. Очистите вывод с помощью strip
  7. И вычтите это (процент холостого хода) из 100, чтобы мы могли получить используемое значение.

Так как он будет спать для 1 second, не беспокойтесь, что это не мгновенная команда.

import subprocess                                      

cmd = "mpstat 1 2 | grep Average | awk '{print $NF}'"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)                                   
out, err = p.communicate()                   
idle = float(out.strip())                              
print(100-idle) 
...