Wenn ich temp.py
in Messen Sie die CPU-Temperatur von Raspeye mit Python ausführe, das ich zuvor geschrieben habe, wird die Anzahl der CPUs jedes Mal gezählt, wenn es in einer while-Schleife ausgelöst wird. Ich habe einen Prozentsatz verwendet.
Da es sich um ein Überwachungsskript handelt, möchte ich es verbessern, da es so leicht wie möglich sein sollte.
Übrigens sieht die Ausgabe nach der Verbesserung so aus. Von links CPU-Temperatur, Häufigkeit, Gesamtnutzungsrate und Nutzungsrate für jeden Kern.
Was schwer war, war das Modul namens "Subprozess", das zum Ausführen von Linux-Betriebssystembefehlen verwendet wurde. Diesbezüglich Es ist falsch, mit Pythons Unterprozess zu katzen. , also schauen Sie bitte. Einfach ausgedrückt ist es langsam, da ein untergeordneter Prozess gestartet wird, um den Text abzurufen. Wenn Sie die integrierte Funktion für den Dateivorgang namens "open ()" verwenden, wird sie nur in Python ausgeführt, sodass sie etwa 50-mal schneller ist.
Es gibt vier Hauptverbesserungen.
subprocess
durch open ()
print
mit Format neuDer erste ist der Höhepunkt dieser Zeit.
Zuvor habe ich "subprocess" verwendet, um einen von Raspberry Pi OS erstellten Befehl namens "vcgencmd" auszuführen.
Dies kann nur unter Raspberry Pi OS ausgeführt werden, und vcgencmd
wurde für die Ausführung in der Shell entwickelt, sodass es nicht für das Schlagen von Python geeignet ist.
Die Überwachung in Python ist eine Unterprozessbombe, die nur ein Name ist. Daher ist sie eine Unterfunktion dieser Zeit, um CPU-Informationen ohne Verwendung von "vcgencmd" abzurufen.
Der zweite ist unbedeutend, aber ich habe ihn in einer Stimmung umgeschrieben. Der dritte dient hauptsächlich der Verbesserung der Lesbarkeit. Viertens fand ich nicht viel Verdienst bei der Überprüfung der Betriebsspannung, und ich konnte die Datei, die die Betriebsspannung aufzeichnete, nicht finden. Geändert, um stattdessen die CPU-Auslastung anzuzeigen.
Hier ist der verbesserte Code.
temp.py
#!/usr/bin/python3.7
import time
import sys
#Funktion zur Erfassung der CPU-Nutzungszeit
def get_data():
with open('/proc/stat') as r: #CPU-Statistikdatei lesen
stats = r.readlines() #Liste nach Zeile
stat = [line.strip().split() for line in stats if 'cpu' in line] #Nehmen Sie die Zeile mit der CPU auf und entfernen Sie das Zeilenvorschubzeichen, doppelte Liste durch Leerzeichen getrennt
rs = [] #Deklarieren Sie eine Liste, die die Nutzungszeit enthält
for data in stat: #Extrahieren Sie Daten für die gesamte CPU und jeden logischen Kern aus Statistiken
busy = int(data[1]) + int(data[2]) + int(data[3]) #Finden Sie die Zeit des Besetztzustands
all = busy + int(data[4]) #Fragen Sie die ganze Zeit
rs.append([all, busy]) #Zur Liste hinzufügen
return rs #Gibt einen Wert zurück
pre_data = get_data() #Holen Sie sich die erste CPU-Auslastungszeit
ave = 0 #Variablendeklaration zur Durchschnittsberechnung
time.sleep(1) #Warten Sie eine Sekunde
try: #Strg mit der folgenden Taste außer Keyboard Interrupt+Normalbetriebsteil zum Fangen C.
for i in range(60): #60 mal wiederholen
with open('/sys/class/thermal/thermal_zone0/temp') as t: #CPU-Temperaturmessung
temp = int(t.read()) / 1000 #Typkonvertierungs- und Übereinstimmungseinheiten
with open('/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq') as f: #CPU-Frequenzmessung
freq = int(f.read()) #Typkonvertierung
now_data = get_data() #Aktuelle CPU-Auslastungszeit abrufen
rates = [] #Deklarieren Sie eine Liste mit der CPU-Auslastung
for j in range(5): #Ganze CPU+Anzahl der logischen Kerne(4)Wiederholen Sie die Zeiten
now = now_data[j] #Extrahieren Sie die gewünschten CPU-Daten aus der aktuellen Nutzungsdauer
pre = pre_data[j] #Extrahieren Sie die gewünschten CPU-Daten aus der Nutzungszeit vor 1 Sekunde
rate = (now[1] - pre[1]) / (now[0] - pre[0]) * 100 #(Besetztzustand/Das ganze) *Finden Sie die CPU-Auslastung bei 100
rates.append(rate) #Fügen Sie der Liste die CPU-Auslastung hinzu
#Formatieren und exportieren Sie mit der Formatierungsmethode
print("Temp:{0:>6.2f}'C, Freq: {1:.2f}GHz, CPU:{2:>5.1f}% [{3:>3.0f},{4:>3.0f},{5:>3.0f},{6:>3.0f}]({7:>2})".format(temp, freq / 1000000, rates[0], rates[1], rates[2], rates[3], rates[4], i + 1))
ave += temp #Addieren Sie die aktuelle Temperatur für die Durchschnittstemperatur
pre_data = now_data #Speichern Sie die aktuellen Daten für die nächsten zweiten vorherigen Daten
time.sleep(1) #Warten Sie eine Sekunde
print("Average: {:.2f}'C (60s)".format(ave / 60)) #Schreiben Sie den Durchschnitt nach dem Ende der Schleife
except KeyboardInterrupt: #Ctrl+Fang C.
sec = i + 1 #Holen Sie sich die verstrichene Zeit am Ende
print(" Aborted.\nAverage: {0:.2f}'C ({1}s)".format(ave / sec, sec)) #Schreiben Sie die Durchschnittstemperatur auf
sys.exit() #Erfolgreiche Fertigstellung
Vor der Erläuterung möchte ich beschreiben, wie die CPU-Auslastungsrate separat berechnet wird. Ich habe auf [hier] verwiesen (http://my-web-site.iobb.net/~yuki/2017-10/raspberry-pi/cpustat/).
Die CPU-Auslastungsrate ist im Grunde das Verhältnis der Zeit, in der die CPU ausgelastet war, zur Gesamtzeit. Wenn Sie also die CPU-Auslastungszeit aus den von Ubuntu bereitgestellten CPU-Statistiken erhalten, können Sie sie nach dem folgenden Prinzip abrufen.
Kumulative CPU-Verfügbarkeit(s) | ... | 904 | 905 | 906 | 907 | 908 | ... |
---|---|---|---|---|---|---|---|
Kumulative Besetztzeit(s) | ... | 302 | 302.5 | 302.6 | 303 | 303 | ... |
Differenzielle CPU-Betriebszeit(s) | ... | 1 | 1 | 1 | 1 | 1 | ... |
Differenz Besetztzeit(s) | ... | - | 0.5 | 0.1 | 0.4 | 0 | ... |
CPU auslastung(%) | ... | - | 50% | 10% | 40% | 0% | ... |
Der allgemeine Codefluss lautet "Datenerfassung (vor)" -> "1 Sekunde warten" -> "Datenerfassung (jetzt und nächste vor)" -> "Berechnung" -> "Datenerfassung (jetzt als nächstes)" -> (Wiederholen) ..
Die Ubuntu-CPU-Statistiken sind in / proc / stat
aufgeführt. Das Folgende ist ein Auszug aus dem Handbuch.
man
/proc/stat
kernel/system statistics. Varies with architecture. Common entries include:
cpu 10132153 290696 3084719 46828483 16683 0 25195 0 175628 0
cpu0 1393280 32966 572056 13343292 6130 0 17875 0 23933 0
#Formatieren Sie die obige Zeichenfolge so, dass sie wie rechts aussieht[[cpu, 10132153, 290696, 3084719, 46828483, 16683, 0, 25195, 0, 175628, 0], [cpu0, 1393280, 32966, 572056, 13343292, 6130, 0, 17875, 0, 23933, 0]]
The amount of time, measured in units of USER_HZ (1/100ths of a second on most architectures, use sysconf(_SC_CLK_TCK) to obtain the right value), that the system ("cpu" line) or the specific CPU ("cpuN" line) spent in various states:
user (1) Time spent in user mode. #Vom Benutzer beschäftigt
nice (2) Time spent in user mode with low priority (nice). #Beschäftigt aufgrund von Prozessen mit niedriger Priorität durch Benutzer
system (3) Time spent in system mode. #Vom System besetzt
idle (4) Time spent in the idle task. This value should be USER_HZ times the second entry in the /proc/uptime pseudo-file. #Idol
Wir werden es so formatieren, dass Sie die erforderlichen Daten abrufen können, indem Sie darauf verweisen. Wenn Sie es mit "subprocess" erhalten, gibt es einen praktischen namens "grep", aber Sie können es diesmal nicht verwenden. Verwenden Sie also die in open () enthaltenen Readlines (). Lesen Sie den Artikel hier, reproduzieren Sie das gleiche Verhalten wie "grep" und verarbeiten Sie es weiter, um "CPU> item" zu verdoppeln. Machen Sie eine Liste. (Siehe Kommentare im obigen Handbuch)
Aus dieser Doppelliste nimmt "for" die Daten für die gesamte CPU und jeden logischen Kern heraus, berechnet den Besetztzustand und die gesamte verstrichene Zeit und gibt sie als Doppelliste der "verstrichenen CPU und des logischen Kerns> verstrichene Zeit" zurück. Hier ist die Summe der 2., 3. und 4. Elemente in der Liste die Summe des Besetztzustands, und die Summe des Besetztzustands und des Leerlaufzustands (das 5. Element) ist die insgesamt verstrichene Zeit. Das Obige ist die Verarbeitung der Nutzungszeiterfassungsfunktion "get_data ()". Danach möchte ich in der Erklärung darauf eingehen.
Ich habe es in den Kommentaren geschrieben, aber ich würde es gerne in der Reihenfolge von oben behandeln. Ich bin selbst ein Anfänger, also werde ich es im Übermaß erklären.
import
Importieren Sie zunächst die erforderlichen Module.
Diesmal habe ich das time
Modul für den Standby und das sys
Modul für die Terminierung geladen.
Darüber hinaus enthielt der vorverbesserte Code "Unterprozess", aber ich habe ihn entfernt.
def get_data()
Wir haben uns bereits in einem anderen Abschnitt mit der CPU-Auslastung befasst, aber wir haben eine Funktion deklariert, um die kumulative Nutzungszeit mit def
zu erhalten.
pre_data
und ave
,time.sleep (1)
Holen Sie sich vor dem Eintritt in die Schleife die Daten für die Erstberechnung und deklarieren Sie eine Variable zur Berechnung der durchschnittlichen CPU-Temperatur.
Warten Sie dann eine Sekunde.
Wenn Sie fortfahren, ohne zu warten, wird now_data
früher als das Aktualisierungsintervall von / proc / stat
erfasst, sodass die Differenz Null ist und Sie wütend werden, wenn Sie nicht durch 0 teilen.
Durch Einschließen der gesamten Schleife in "try" kann die Eingabe von "Strg + C" als Ausnahme anstelle eines Fehlers abgefangen werden. Wenn "Strg + C" eingegeben wird, springt es zu "außer Tastaturunterbrechung", berechnet die Durchschnittstemperatur und endet dann normal.
for i in range(60)
Es wiederholt den Vorgang, während i durch Zahlen von 0 bis 59 ersetzt wird.
Es scheint, dass 10000000-maliges Wiederholen schneller ist als das Wiederholen mit "while" für etwa 0,04 Sekunden.
Diesmal liegt es nicht im Fehlerbereich, aber ich mag die Tatsache, dass ich keinen Zähler vorbereiten muss, weil er intelligent ist.
with open()
Eine integrierte Funktion, die die Datei öffnet, die im Auftrag von "subprocess" eingeführt wurde.
Wie oben erwähnt, finden Sie Einzelheiten hier hier.
Da die Verarbeitung in Python abgeschlossen ist, trägt sie zur Gewichtsreduzierung bei.
now_data
und Rates
Sie erhalten die aktuelle kumulative CPU-Auslastungszeit. Deklariert eine leere Liste zum Ersetzen der CPU-Auslastung.
for j in range(5)
Daten werden für die gesamte CPU und jeden Kern abgerufen und verarbeitet.
Berechnet die CPU-Auslastung, indem die Differenz zwischen der aktuellen kumulierten Nutzungszeit now_data
und der kumulierten Nutzungszeit pre_data
vor einer Sekunde berechnet wird, und gibt das Ergebnis als Liste zurück.
(Wie soll ich einen Index nennen, der nicht "i" ist?)
print
Es ist so geschrieben, dass es mit der Formatmethode leicht zu erkennen ist.
Dies ist sehr praktisch, da Sie einfache Berechnungen durchführen können, z. B. den Durchschnittswert innerhalb des Formats teilen.
ave
und pre_data
,time.sleep (1)
Die aktuelle Temperatur wird zu "ave" addiert, um die durchschnittliche Temperatur zu erhalten. Ersetzen Sie "pre_data" durch die zuvor erhaltenen aktuellen Daten für die nächste Berechnung der CPU-Auslastung. Nach einer Sekunde Wartezeit wird der Prozess wiederholt.
vcgencmd
zu verwendenWie bereits erwähnt, ist das Abrufen von Informationen aus Python mit vcgencmd
sehr ineffizient.
Da die Daten von Ubuntu wie / proc / stat
in eine Datei umgewandelt werden, habe ich versucht, sie von dort abzurufen.
Ich denke, das ist ein ziemlich berühmter Ort.
cat /sys/class/thermal/thermal_zone0/temp
#1000-fache Temperatur wird ausgegeben
Mit vcgencmd
werden Einheiten usw. angehängt, aber da es sich nur um eine Zahl handelt, scheint es besser, sie von hier aus in das Skript einzubetten.
Teilen ist kein Problem, wenn es im Programm enthalten ist, und aus irgendeinem Grund ist es gut, dass die gültigen Zahlen größer sind.
Es fiel mir schwer, das zu finden, aber auf jeden Fall gibt es großartige Männer. Vielen Dank.
Ubuntu CPUfreq Teil 3 - Informationen zu den Dateien im Ordner cpufreq der CPU
#/sys/devices/system/cpu/cpu*/CPU-Frequenz zu CPU(Ader)Informationen werden gesammelt
#cpuinfo_cur_freq ist der von der Hardware erhaltene Wert
#scaling_cur_freq ist der vom Linux-Kernel erhaltene Wert
cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
#Permission denied
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
#Die CPU-Frequenz von cpu0 wird angezeigt
Es ist schön, einen Platz zu finden, aber ich hatte zwei Probleme. Das erste ist, dass Sie "root" nur für die von der Hardware erhaltenen Zahlen sehen können, und das andere ist, dass die Dateien für jeden CPU-Kern unterschiedlich sind. Wenn möglich, möchte ich auf den von der Hardware erhaltenen numerischen Wert verweisen, möchte ihn jedoch ohne "root" ausführen. Wenn die Frequenz für jeden CPU-Kern unterschiedlich ist, möchte ich den Durchschnitt nehmen, aber ich möchte ihn vermeiden, da sich die Verarbeitung vervierfacht.
Um diese Probleme zu lösen, habe ich versucht, sie mit brutaler Gewalt zu überprüfen.
Wenn alle acht Werte übereinstimmen, gibt es meines Erachtens auch dann kein Problem, wenn ein Wert als repräsentatives Beispiel verwendet wird. Erfassen und vergleichen Sie also 10000 Mal "cpuinfo_cur_freq" und "scaling_cur_freq" aller 4 Kerne.
Infolgedessen stimmten alle mit einer Rate von etwa 95% überein.
Es scheint, dass es eine Verschiebung beim Ändern der Frequenz gibt, und wenn Sie zwischen den Überprüfungen einen Schlaf einlegen, waren es ungefähr 95%, und wenn Sie nichts getan und wiederholt haben, war es 100% konsistent.
Es scheint auch, dass die Abweichung hauptsächlich zwischen der Hardware und dem Kernel auftritt und die Übereinstimmung zwischen den Kernen im schlimmsten Fall etwa 99% betrug.
Es muss nicht so streng sein, und das Abtasten jeder Sekunde hat nur geringe Auswirkungen. Deshalb habe ich mich dieses Mal entschieden, scaling_cur_freq
von cpu0
als repräsentativen Wert zu verwenden.
Unter Linux (in Raspberry Pi?) Steuern Sie nicht, wie Sie Strom sparen, indem Sie die Frequenz für jeden Kern ändern. Ich würde mich freuen, wenn Sie mich wissen lassen könnten, ob jemand mit diesem Bereich vertraut ist.
Wir konnten den Speicherort der Datei nicht finden. Sie können es finden, wenn Sie ernsthaft danach suchen, aber da es ein Wert war, der ursprünglich nicht sein musste, habe ich beschlossen, ihn zu diesem Zeitpunkt zu schneiden. Wenn jemand weiß, lassen Sie es mich bitte wissen.
Ich fing an, das Gewicht schwerer Skripte zu reduzieren, und da ich die CPU mit Python überwachte, fügte ich den Zweck hinzu, sie nur mit Python zu vervollständigen, und am Ende gelang es mir, das Gewicht signifikant zu reduzieren. Ich bin mir meiner täglichen Studien sehr bewusst, weil ich etwas über super nützliche Funktionen lernen kann, die ich nicht kannte. Ich konnte es auch ein wenig verfeinern, indem ich den Code beim Schreiben dieses Artikels neu schrieb. Überprüfung ist wichtig. Es war ein langer Artikel, aber danke, dass Sie bis zum Ende gelesen haben. Wenn Sie Vorschläge haben, können Sie sich gerne an uns wenden.
Recommended Posts