2016-11-10 34 views
0

Ich habe einen Thread, wo ich ein Thread-Ereignis verwenden, um den Thread von außerhalb der Zielfunktion zu steuern.Python Threading Event

flag = threading.event() 

In meiner Zielfunktion, ich habe so etwas wie dies:

def functionname(arguments): 
    flag.clear() 
    while not flag.wait(timeout = 0.5): 
     # do something. 

, wenn ich den Faden zurückkehren möchten, von meiner Hauptfunktion sage ich, flag.set(). Dann wird flag auf true gesetzt, meine Zielfunktion beendet die Ausführung und der Thread ist abgeschlossen.

Nun, wenn ich flag.wait (timeout = 5) in meiner Hauptfunktion verwenden möchte, erwarte ich, zu blockieren und warten Sie fünf Sekunden, um den "etwas tun" Teil des Codes auszuführen. Allerdings sehe ich, dass der "etwas tun" Teil des Codes alle 0,5 Sekunden wie üblich ausgeführt wird und meine Hauptfunktion für fünf Sekunden blockiert ist.

Die Wartemethode muss blockieren, bis das Flag wahr ist oder das optionale Timeout endet. Es blockiert meine Hauptfunktion und nicht die Zielfunktion. Kann jemand wissen, warum das sein könnte?

PS: I definiert das Flag Ereignis in meinem Hauptfunktion und übergeben sie als ein Argument an die Zielfunktion

+0

ich verwirrt bin .... Sie tun 'flag.wait (timeout = 5)' und Sie möchten, dass die Threads 'flag.wait (timeout = 0,5)' warten 5 Sekunden lang machen, anstatt ? Das funktioniert nicht. Das Zeitlimit des Hauptthreads ist unabhängig vom Kind. Was ist dein Ziel? Möchten Sie steuern, wie lange das Kind im Hauptthread wartet? – tdelaney

+0

Der Flag.wait (Timeout = 0,5) wird anfänglich geschrieben, wenn die Zielfunktion alle 0,5 Sekunden ausgeführt werden soll. Jetzt, wenn ich es zu 5 Sekunden ändern möchte, verwende ich flag.wait (5). Das Flag ist ein Threading-Ereignis, das nur für die Zielfunktion und nicht für den Hauptthread ausgeführt werden sollte. –

Antwort

0

viele Threads wartet auf ein Ereignis in der gleichen Zeit und wie lange man vor dem Timeout unabhängig ist warten kann von wie lange die anderen tun. Wenn Sie möchten, dass sich die Wartezeit Ihres Threads von 0,5 auf 5 Sekunden ändert, müssen Sie dem Thread sagen, dass er den übergebenen Wert im Timeout-Parameter ändern soll. Dies scheint ein guter Job für eine gemeinsam genutzte Variable zu sein - der Thread liest Timeout von der Variablen und main kann diese Variable ändern.

Aber wo stellst du es hin? Nun, Klasseninstanzen existieren, um assoziierte Daten zu halten, so dass eine Klasse, die das Ereignis enthält, und der aktuelle Zeitüberschreitungswert vernünftig ist. In der Tat können Sie einfach Vererbung verwenden, um die Aufgabe zu erledigen. Beachten Sie, dass in diesem Beispiel das Zeitlimit nur für das nächste Intervall geändert wird - der Thread wartet die aktuelle Wartezeit, bevor er den aktualisierten Wert verwendet. Die Änderung sofort zu bekommen ist wesentlich schwieriger und ich wollte die Sache nicht verwirren.

import threading 
import time 

class VariablyTimedEvent(threading.Event): 

    def __init__(self, initial_timeout=None): 
     super().__init__() 
     self.timeout = initial_timeout 

    def wait(self): 
     return super().wait(timeout=self.timeout) 

# ------------- test ----------------- 

def functionname(event): 
    event.clear() 
    while not event.wait(): 
     do_something() 
    print('event set, exiting') 

_do_something_start = time.time() 
def do_something(): 
    # a mock object that shows time since program start 
    print('%03.1f: do something' % (time.time() - _do_something_start)) 

print("start timing at .5 second") 
event = VariablyTimedEvent(.5) 
thread = threading.Thread(target=functionname, args=(event,)) 
thread.start() 
time.sleep(3.1) 
print("change timeout to 2 seconds") 
event.timeout = 2 
time.sleep(7) 
print("exit the thread") 
event.set() 
thread.join()