Ich brauche eine sleep()
Methode, die abgebrochen werden kann (wie beschrieben hier oder hier ).
Mein Ansatz ist es, ein threading.Event.wait()
timeout auf die angegebene Dauer zu setzen:
Nach dem Aufruf von abortable_sleep(10, _abort)
kann ich jetzt (von einem anderen Thread) _event.set(_abort)
aufrufen, um abortable_sleep()
vor den 10 Sekunden beenden zu lassen.
Beispiel:
%Vor%Ausgabe:
%Vor%Dieser Code funktioniert wie erwartet, aber ich habe noch einige Fragen:
sleep()
was kann abgebrochen werden? Event
sein, die nicht an eine Instanz von abortable_sleep()
gebunden ist.
while True: abortable_sleep(0.0001)
erwarten? Wie ist die Wartezeit () - Timeout implementiert? Ich habe eine Wrapper-Klasse, die im Grunde einige Sleep-Semantiken auf ein Event
legt. Das Schöne ist, dass Sie nur ein Objekt Sleep
weitergeben müssen, das Sie sleep()
mehrmals aufrufen können, wenn Sie möchten ( sleep()
ist nicht threadsicher) und dass Sie wake()
von einem anderen Thread verwenden können .
Anwendungsbeispiel:
%Vor%Das obige gibt vielleicht etwas aus:
%Vor%Genau das, was Sie getan haben, aber in einer Klasse gekapselt.
Ich würde die Schlaf / Abbruch-Funktion in eine neue Klasse einfügen:
%Vor% Ich würde dann auch eine Thread
Unterklasse angeben, um die gemeinsame Nutzung der Aufwachroutine pro Thread zu verwalten:
Jeder andere Thread mit Zugriff auf diesen Thread kann wakeup()
aufrufen, um den aktuellen abortable_sleep()
abzubrechen (falls einer läuft).
Sie können Threads mit der Klasse ThreadWithWakeup
erstellen und sie folgendermaßen verwenden:
Die Ausgabe sieht wie folgt aus:
%Vor% Sie können auch die Klasse AbortableSleep
selbst verwenden, was praktisch ist, wenn Sie die Klasse ThreadWithWakeup
aus irgendeinem Grund nicht benutzen können (vielleicht sind Sie im Hauptthread, vielleicht kreiert etwas anderes die Threads für Sie usw.):
Aufgrund der Rennbedingungen ist Ihre Lösung nicht immer perfekt. Sie sollten stattdessen eine threading.BoundedSemaphore()
verwenden. Rufen Sie aquire()
sofort nach dem Erstellen auf. Wenn Sie schlafen möchten, rufen Sie acquire()
mit einer Zeitüberschreitung auf und rufen Sie dann release()
auf, wenn acquire()
true zurückgegeben hat. Um den Schlaf vorzeitig zu beenden, rufen Sie release()
von einem anderen Thread auf. Dies wird ValueError
erhöhen, wenn kein Schlaf ausgeführt wird.
Die Verwendung eines Ereignisses ist jedoch problematisch, wenn der andere Thread set()
zur falschen Zeit aufruft (d. h. zu einem anderen Zeitpunkt, als wenn Sie tatsächlich auf das Ereignis warten).
Tags und Links python thread-sleep