Ich benutze Python, um eine Hardware-USB-Sniffer-Gerät mit der Python-API des Anbieters Schnittstelle und ich versuche, (USB-Pakete) von dem Gerät in einem separaten Thread in einer Endlosschleife (was gut funktioniert). Das Problem ist, dass meine Hauptschleife anscheinend nie wieder eingeplant wird (meine Leseschleife bekommt die ganze Aufmerksamkeit).Scheduling-Probleme in Python
Der Code sieht ähnlich wie folgt aus:
from threading import Thread
import time
usb_device = 0
def usb_dump(usb_device):
while True:
#time.sleep(0.001)
packet = ReadUSBDevice(usb_device)
print "packet pid: %s" % packet.pid
class DumpThread(Thread):
def run(self):
usb_dump()
usb_device = OpenUSBDevice()
t = DumpThread()
t.start()
print "Sleep 1"
time.sleep(1)
print "End"
CloseUSBDevice(usb_device)
sys.exit(0)
(Ich konnte eigentlichen Code einfügen, aber da Sie die Hardware-Gerät benötigen dar, dass ich es nicht viel helfen).
Ich erwarte, dass dieser Code beginnt, usb-Pakete für etwa eine Sekunde zu entladen, bevor der Haupt-Thread das gesamte Programm beendet. Alles, was ich sehe, ist "Sleep 1" und dann läuft die usb_dump()
Prozedur für immer. Wenn ich die "time.sleep (0.001)" -Anweisung in der inneren Schleife der usb_dump()
-Prozedur auskommentiere, fangen die Dinge an zu arbeiten, wie ich es erwarte, aber dann wird der Python-Code nicht mehr mit allen eingehenden Paketen mithalten können :-(
Der Verkäufer sagt mir, dass dies ein Python-Scheduler Problem ist, und ihre api nicht Schuld und dafür wird mir nicht helfen.
«Allerdings scheint es, wie Sie einige Nuancen erleben, wenn sie in Python threading von Wenn Sie den time.sleep in den DumpThread-Thread setzen, signalisieren Sie dem Python-Threading-System explizit, die Kontrolle aufzugeben, andernfalls ist es der Python-Interpreter, zu bestimmen, wann ein Thread gewechselt werden soll, und normalerweise nach einem bestimmten Anzahl der Byte-Code-Anweisungen wurden ausgeführt. »
Kann jemand bestätigen, dass Python das Problem hier ist? Gibt es eine andere Möglichkeit, die DumpThread-Versionskontrolle zu machen? Irgendwelche anderen Ideen?
Auf Ihre Notizen: Ich weiß, dass der Code hässlich aussieht. Ich begann mit einem Beispielcode vom Anbieter und machte so wenig Änderungen wie möglich, während ich immer noch meinen Standpunkt zeigte. Ich dachte, sie würden ihr eigenes Beispiel kennen ... Das ist überhaupt kein Produktionscode. –
Ok, wenn ich also annehme, dass die C-Erweiterung (die hinter dem ReadUSBDevice-Aufruf liegt) die GIL nicht freigibt (wie es sollte), dann fügt ein kleiner Schlaf (wie ich es versucht habe) den Code wie erwartet funktionieren, weil jetzt Ich gebe die GIL bei jeder Iteration explizit frei. Das würde das Verhalten erklären, das ich sehe. Gibt es eine andere Möglichkeit, die GIL freizugeben? Vielleicht kann ich ein wenn alle 50 Runden von etwas schläft? –
Es liegt in der Verantwortung Ihres Anbieters, die GIL freizugeben, und Sie können nicht viel dagegen tun. Was ist mit einem threading.Timer-Objekt? Es würde automatisch die Semantik Ihrer Funktion (periodische Umfrage) implementieren und Sie müssten sich nicht um deren Implementierung kümmern. –