Python - threading.Timer在调用cancel()方法后保持活动状态

时间:2012-06-18 12:55:15

标签: python multithreading

我在以下代码中注意到以下行为(使用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

正如我们从输出中注意到的那样,计时器对象仍处于活动状态并且同时完成。

事实上,我想将相似的功能调用数百次,我想知道那些“活着”的定时器是否会影响性能。

我想以正确的方式停止或取消计时器对象。我做得对吗?

谢谢

2 个答案:

答案 0 :(得分:12)

你应该使用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

答案 1 :(得分:10)

TimerThread的子类,其implementation非常简单。它通过订阅活动finished等待提供的时间。

因此,当您通过Timer.cancel设置事件时,可以保证不会调用该函数。但不保证Timer线程将直接继续(并退出)。

所以关键是计时器的线程在cancel执行后仍然可以处于活动状态,但该函数不会被执行。因此,检查finished是安全的,而在这种情况下,测试Thread.is_alive(更新的API,使用此!)是一种竞争条件。

提示:您可以在致电time.sleep后放置cancel来验证这一点。然后它就会打印出来:

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