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