2012-06-07 9 views
21

Ich versuche, mit einem Gerät über serielle Verbindung mit Pyserial zu kommunizieren. Da Befehle ständig gesendet werden müssen, müssen sie in einer While-Schleife in Python platziert werden.Effiziente und schnelle Python While-Schleife bei Verwendung von Schlaf()

Ich bin derzeit mit diesem Code und habe einen Blick auf python process takes 100% CPU genommen:

while True: 
    #do some serial sending here 
    time.sleep(0.2) 

Dieser Code funktioniert. Die Sendegeschwindigkeit ist jedoch langsam. Ich versuchte es schneller zu machen, indem ich das sleep Intervall verringerte, aber es scheint, die CPU ein bisschen zu viel zu laden.

Kurz gesagt, gibt es eine Möglichkeit, effektiv über eine While-Schleife für immer zu iterieren, während immer noch ein geringer Verbrauch von CPU-Ressourcen beibehalten wird?

+0

basierend auf diesem [post] (http://stackoverflow.com/questions/529034/python-pass-or-leep-for-long-running-processes), time.sleep hat sehr wenig Overhead, möchten Sie vielleicht Überprüfen Sie Ihre serielle Übertragung Teil des Codes – xvatar

+1

Haben Sie versucht, für 0,00001 schlafen? Es mag lächerlich erscheinen, aber diese Verzögerung kann den ganzen Unterschied in der Welt für Ihre CPU ausmachen. Versuch es bitte. – jakebird451

+0

Wie kann ein moderner Computer Schweiß an eine serielle Schnittstelle schreiben? Würde nicht serial.Serial(). Write() während des Schreibens blockieren? Das scheint reichlich Zeit für die CPU, andere Dinge zu tun? – Bittrance

Antwort

37

Die langsame CPU-Verschwendung Teil ist die "tun serielle senden". Die While-Schleife mit nur einem kurzen Schlaf wird vernachlässigbare CPU verwenden.

Können Sie den seriellen Sendecode anzeigen? Es kann einen Weg geben, das zu beschleunigen.

Auf diesem eher langsam CPU ich sehe:

import time 
while True: time.sleep(0.2)  # 0% CPU 
while True: time.sleep(0.02)  # 0% CPU 
while True: time.sleep(0.002) # 0.5% CPU 
while True: time.sleep(0.0002) # 6% CPU 
while True: time.sleep(0.00002) # 18% CPU 

Jetzt in der Schleife einige zusätzliche Arbeit tun:

import time 
while True: range(10000) and None; time.sleep(0.2)  # 1% CPU 
while True: range(10000) and None; time.sleep(0.02)  # 15% CPU 
while True: range(10000) and None; time.sleep(0.002) # 60% CPU 
while True: range(10000) and None; time.sleep(0.0002) # 86% CPU 

I, in dem Interpreter lief und hielt jede while-Schleife mit ctrl- C.

+0

Alternativ könnte ich die Weitergabe mit einem Schalter auf serielle Schnittstelle beschränken, jedoch bedeutet das auch, dass das eingebettete Gerät neu programmiert wird. Der Code sieht so etwas wie \t command = 'w' \t während True: \t \t if (command = x!): \t \t \t #pyserial die Zeichenfolge senden hier, in diesem Fall w. geändert durch externen Handler. \t \t anderes: \t \t \t #tell pyserial schließen Verbindung – jhtong

+0

Sieht aus wie ich sowohl eine Schaltprüfung auf den Computer zu implementieren und der Mikroprozessor Seite gesendet, um die Anzahl von Befehlen zu reduzieren. Bleiben Sie dann im Ruhezustand (0.2), damit die CPU-Auslastung nicht so hoch ist. d. h. speichern Sie den letzten Befehl, und wenn er gesendet wurde, senden Sie ihn nicht noch einmal. währenddessen wartet der Mikroprozessor auf einen Haltebefehl 'x'. Wird sie nicht empfangen, wird der aktuelle/vorherige Befehl in seinem eigenen Tempo weiter verarbeitet. – jhtong

+0

Wenn Sie Mikrocontroller sind, wird "weiterhin den aktuellen Befehl in seiner eigenen Geschwindigkeit verarbeiten", dann ist eine while-Schleife auf Ihrem Python-Code nicht erforderlich. Ich bezweifle, dass irgendeine Art von Bibliothek für die Kommunikation der seriellen Schnittstelle _require_ Sie jede Art von While-Schleife aufrufen würde. Vielleicht lesen Sie die Bibliotheksdokumentation erneut, da es sich anhört, als würden Sie es falsch benutzen. –

3

Sie müssen herausfinden, welchen Kompromiss Sie zwischen Geschwindigkeit und CPU-Last eingehen möchten.

Wenn Sie kurze Ausbrüche von Daten senden müssen, die zwar nicht so viel zwischen den Nachrichten zu tun, dann können Sie vielleicht mit hohen CPU-Last für eine kurze Zeit leben als der Durchschnitt immer noch niedrig sein könnte.

+0

Danke, das könnte bedeuten, den Mikrocontroller umzuprogrammieren, um Schalter zu verwenden. Es muss vorwärts gehen, daher muss "w" gesendet werden. Wenn kein "w" Schlüssel erkannt wird, bewegt sich der Motor nicht. Daher wird der Motor, wenn er zu langsam gesendet wird, noch langsamer bewegt. – jhtong

4

In Bezug auf Ihren Kommentar zu Joachim Antwort:

Dann wird Ihr Mikrocontroller-Code ein Redesign benötigt. Sonst verwandeln Sie Ihren Allzweck-Computer in nichts mehr als einen dummen "Mikrocontroller", der wiederholt über unnötigen Code iteriert, daher die 100% ige CPU. Ein weiteres Symptom für die falsche Verwendung Ihres Computers ist die Tatsache, dass die Geschwindigkeit Ihres Hardwaremotors von der Geschwindigkeit abhängt, mit der Sie ihm Befehle über die serielle Schnittstelle senden. Sie müssen es mit dem Computer "befehlen", der Ihre High-Level-Logik hostet. Und Ihr Mikrocontroller muss die Kontrolle auf niedrigem Niveau des Motors übernehmen.

+1

+1 für das Lesen zwischen den Zeilen. – Vorac

Verwandte Themen