线程的生存期。退出范围后的计时器

时间:2018-08-07 16:25:49

标签: python python-multithreading

假设我有一个函数可以启动Timer来调用其他方法foo

def set_a_timer():
    my_timer = threading.Timer(1200, foo)
    my_timer.start()
    ...
    return None

现在,此函数将在定时器完成之前返回,并且可能直到1200秒结束后才在我的程序中再次调用。程序一直保持运行状态。

我知道,垃圾回收通常会清除范围外的变量。这意味着我将无法再在程序中访问my_timer。很好-我需要的是在1200秒内执行它。但是它会在这1200秒后仍然执行foo,还是会在有机会之前被垃圾收集器清理掉?

1 个答案:

答案 0 :(得分:1)

简单的答案是:计时器仍将运行。

长答案是您在此处混淆变量和值。变量超出范围,但这对价值没有任何作用。 (与del相同;它只是删除变量,而不是值。)

仅当最后一个对值的引用消失时,该值才变为垃圾。 (在CPython中,如果该值不在参考周期中,则意味着它会立即被销毁;在大多数其他实现中,只要GC注意到,它就会在稍后销毁。)

Timer类是Thread的子类。线程通过在后台线程中调用run方法来工作。该方法的堆栈框架引用了它所需的任何内容,例如函数对象本身,以及所有局部变量,就像每个函数一样,因此这些值在该方法完成之前不会变成垃圾。这些本地变量之一是self,因此Timer对象本身仍被引用,因此不会造成垃圾。

(如果您查看来自文档的Timer的源代码,您可以看到它的run方法所做的基本上就是在Event上等待1200秒,然后调用您的foo函数。)

如果您想查看Timer对象何时被销毁,可以对其进行子类化,并添加一个__del__方法来打印一条消息(或者在该点上甚至打印整个堆栈)。