2012-06-18 16 views
12

ho notato il seguente comportamento nel codice seguente (utilizzando la classe Threading.Timer):Python - Threading.Timer rimane vivo dopo aver chiamato cancel() metodo

import threading 

def ontimer(): 
    print threading.current_thread() 

def main(): 
    timer = threading.Timer(2, ontimer) 
    timer.start() 
    print threading.current_thread() 
    timer.cancel() 
    if timer.isAlive(): 
     print "Timer is still alive" 
    if timer.finished: 
     print "Timer is finished" 


if __name__ == "__main__": 
main() 

L'uscita del codice è:

<_MainThread(MainThread, started 5836)> 
Timer is still alive 
Timer is finished 

Come si nota dall'output, che l'oggetto timer è ancora vivo e terminato nello stesso tempo.

In effetti, mi piacerebbe chiamare una funzione simile centinaia di volte, e mi chiedo se quei timer "viventi" possano influenzare le prestazioni.

Vorrei interrompere o annullare l'oggetto del timer in modo corretto. Lo sto facendo bene?

Grazie

risposta

11

Un Timer è una sottoclasse di un Thread e la sua implementation è davvero semplice. Aspetta il tempo previsto iscrivendosi all'evento finished.

Così quando si imposta l'evento per Timer.cancel è garantito che la funzione non viene chiamata. Ma non è garantito che il thread Timer continui direttamente (ed esca).

Quindi il punto è che il thread del timer può essere ancora vivo dopo l'esecuzione di cancel, ma la funzione non verrà eseguita. Quindi verificare finished è sicuro, mentre il test per Thread.is_alive (API più recente, usa questo!) È una condizione di competizione in questo caso.

Suggerimento: è possibile verificare questo mettendo un time.sleep dopo aver chiamato cancel. Poi sarà solo la stampa:

<_MainThread(MainThread, started 10872)> 
Timer is finished 
10

È consigliabile utilizzare il thread.join() aspettare fino a filo del timer è davvero finito e puliti.

import threading 

def ontimer(): 
    print threading.current_thread() 

def main(): 
    timer = threading.Timer(2, ontimer) 
    timer.start() 
    print threading.current_thread() 
    timer.cancel() 
    timer.join()   # here you block the main thread until the timer is completely stopped 
    if timer.isAlive(): 
     print "Timer is still alive" 
    else: 
     print "Timer is no more alive" 
    if timer.finished: 
     print "Timer is finished" 


if __name__ == "__main__": 
main() 

questo display:

<_MainThread(MainThread, started 5836)> 
Timer is no more alive 
Timer is finished 
+0

Grazie per l'elaborazione. –

Problemi correlati