2012-06-18 51 views
12

我注意到下面的代碼以下行爲(使用threading.Timer類):的Python - threading.Timer呼籲取消後保持活着()方法

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

代碼的輸出是:

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

正如我們從輸出中注意到的那樣,計時器對象仍處於活動狀態並在同一時間完成。

事實上,我想調用一個類似的函數數百次,我不知道那些「活着」的定時器是否會影響性能。

我想以適當的方式停止或取消計時器對象。我做對了嗎?

謝謝

回答

11

一個TimerThread的子類,其implementation是非常簡單的。它通過訂閱事件finished等待提供的時間。

因此,當您通過Timer.cancel設置事件時,可以保證函數不會被調用。但不能保證Timer線程將直接繼續(並退出)。

所以問題是在執行cancel之後定時器的線程仍然可以活着,但函數不會被執行。因此,檢查finished是安全的,而在這種情況下,測試Thread.is_alive(較新的API,使用此!)是一種競爭條件。

提示:您可以在致電cancel之後放置time.sleep以驗證此情況。然後,它會只是打印:

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

您應該使用thread.join()等到你的計時器的線程是真正完成和清潔。

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

這將顯示:

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

謝謝你闡述。 –