【问题标题】:Python - threading.Timer stays alive after calling cancel() methodPython - threading.Timer 在调用 cancel() 方法后保持活动状态
【发布时间】:2012-06-18 12:55:14
【问题描述】:

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

我们从输出中注意到,计时器对象仍然处于活动状态并同时完成。

其实我想调用一个类似的函数数百次,我想知道那些“活”的计时器是否会影响性能。

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

谢谢

【问题讨论】:

  • timer.finished 替换为timer.finished.is_set()timer.finished 属性不是布尔值,它是 _Event 对象,因此检查 if timer.finished 会产生误导(因为它总是会计算为 True)
  • 有时会被认为是“不活着”,尝试在“timer.cancel()”之后添加睡眠1或2秒,它会正常工作。

标签: python multithreading


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    TimerThread 的子类,它的implementation 非常简单。它通过订阅事件finished来等待提供的时间。

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

    所以重点是timer的线程在cancel执行后还可以存活,但是函数不会被执行。所以检查finished 是安全的,而测试Thread.is_alive(较新的API,使用这个!)在这种情况下是一种竞争条件。

    提示:您可以通过在调用cancel 之后放置time.sleep 来验证这一点。然后它只会打印:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-09
      • 2014-11-16
      • 2014-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多