abortable sleep () in Python

8

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:

%Vor%

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:

  • gibt es nicht einen leichter Weg, um etwas zu erreichen. likea sleep() was kann abgebrochen werden?
  • kann dies eleganter getan werden? Z.B. Auf diese Weise muss ich vorsichtig mit der Instanz Event sein, die nicht an eine Instanz von abortable_sleep() gebunden ist.
  • Muss ich Performance-Probleme mit hochfrequenten Loops wie while True: abortable_sleep(0.0001) erwarten? Wie ist die Wartezeit () - Timeout implementiert?
frans 12.02.2015, 13:08
quelle

3 Antworten

3

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 .

%Vor%

Anwendungsbeispiel:

%Vor%

Das obige gibt vielleicht etwas aus:

%Vor%

Genau das, was Sie getan haben, aber in einer Klasse gekapselt.

    
André Laszlo 12.02.2015, 14:22
quelle
1

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:

%Vor%

Jeder andere Thread mit Zugriff auf diesen Thread kann wakeup() aufrufen, um den aktuellen abortable_sleep() abzubrechen (falls einer läuft).

Verwenden von ThreadWithWakeup

Sie können Threads mit der Klasse ThreadWithWakeup erstellen und sie folgendermaßen verwenden:

%Vor%

Die Ausgabe sieht wie folgt aus:

%Vor%

AbortableSleep selbst verwenden

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.):

%Vor%     
Jamie Cockburn 12.02.2015 14:59
quelle
0

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).

    
Kevin 12.02.2015 14:24
quelle

Tags und Links