这里是一个测试的例子:
在第二种方法中,线程被激活后会结束吗?还是会保留在内存中并启动一个新的线程?(多个线程)
import threading
def keepalive():
print 'Alive.'
threading.Timer(200, keepalive).start()
print threading.active_count()
threading.Timer(200, keepalive).start()
我还将200改为0.2,以便时间不会太长。
线程计数一直是3。
然后我做了这个:
top -pid 24767
#TH列从未改变。
因此,这就是答案:我们没有足够的信息来知道Python是否为所有计时器维护单个计时器线程,或者在计时器运行后立即结束和清理线程,但我们可以确定线程不会停留并堆积。(如果您确实想知道前者中发生了什么,可以打印线程ID。)
另一种查找方法是查看源代码。正如
文档所说,“Timer是Thread的子类,因此也可以作为创建自定义线程的示例”。它是
Thread
的子类已经告诉您每个
Timer
都是一个
Thread
。而它“作为示例运行”这一事实意味着它应该很容易阅读。如果您点击文档中的链接
源代码,您可以看到它是多么简单。大部分工作由
Event
完成,但它在同一个源文件中,并且几乎一样简单。实际上,它只创建了一个条件变量,在它上面等待(因此它会阻塞直到超时或通过调用
cancel
通知条件),然后退出。
我回答一个子问题并解释我是如何做到的,而不是回答每个子问题,因为我认为通过相同的步骤更有用。
进一步思考后,这可能不是首先需要通过优化来决定的问题:
如果您有一个简单的同步程序需要在200秒内不做任何事情,请调用阻塞式的
sleep
。或者更简单地,只需完成工作并退出,选择一个外部工具来安排脚本每200秒运行一次。
另一方面,如果您的程序本质上是异步的——特别是如果您已经有了线程、信号处理程序和/或事件循环——那么您绝对无法让
sleep
起作用。如果
Timer
效率太低,去PyPI或ActiveState找到一个更好的定时器,它可以让您使用单个实例和线程安排可重复的定时器(甚至多个定时器)。 (或者,如果您正在使用信号,请使用
signal.alarm
或
setitimer
,如果您正在使用事件循环,请将计时器构建到主循环中。)
我想不出任何情况下,
sleep
和
Timer
都会成为严肃的竞争者。
threading.active_count()
),这可能比你提出一个合理的问题所需的时间更短。 - abarnert