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

Aba*_*h A 14 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()
Run Code Online (Sandbox Code Playgroud)

代码的输出是:

<_MainThread(MainThread, started 5836)>
Timer is still alive
Timer is finished
Run Code Online (Sandbox Code Playgroud)

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

事实上,我想将相似的功能称为数百次,我想知道那些"活着"的定时器是否会影响性能.

我想以适当的方式停止或取消计时器对象.我做得对吗?

谢谢

Céd*_*ien 13

您应该使用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()
Run Code Online (Sandbox Code Playgroud)

这将显示:

<_MainThread(MainThread, started 5836)>
Timer is no more alive
Timer is finished
Run Code Online (Sandbox Code Playgroud)


sch*_*mar 10

A Timer是a的子类,Thread实现非常简单.它通过订阅活动等待提供的时间finished.

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

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

提示:您可以通过time.sleep拨打电话进行验证cancel.然后它将打印:

<_MainThread(MainThread, started 10872)>
Timer is finished
Run Code Online (Sandbox Code Playgroud)