如何在Python中每60秒asynchronous执行一次函数?
我想在Python上每60秒执行一个函数,但是我不想在此期间被阻塞。
我怎样才能asynchronous做到这一点?
import threading import time def f(): print("hello world") threading.Timer(3, f).start() if __name__ == '__main__': f() time.sleep(20)
使用此代码,函数f在20秒内每3秒执行一次。 最后它给出了一个错误,我认为这是因为threading.timer还没有被取消。
我怎样才能取消它?
提前致谢!
你可以尝试threading.Timer类: http : //docs.python.org/library/threading.html#timer-objects 。
import threading def f(f_stop): # do something here ... if not f_stop.is_set(): # call f() again in 60 seconds threading.Timer(60, f, [f_stop]).start() f_stop = threading.Event() # start calling f now and every 60 sec thereafter f(f_stop) # stop the thread when needed #f_stop.set()
这取决于你在此期间想要做什么。 线程是最普遍和最不优选的方式; 你应该知道线程在使用时的问题:并不是所有的(非Python)代码都允许同时从多个线程访问,线程之间的通信应该使用Queue.Queue
这样的线程安全的数据结构来完成,你不会能够从外部中断线程,并且在线程仍在运行时终止程序可能导致挂起的解释器或虚假回溯。
通常有一个更简单的方法。 如果您在GUI程序中这样做,请使用GUI库的计时器或事件function。 所有的GUI都有这个。 同样,如果您正在使用另一个事件系统(如Twisted或另一个服务器进程模型),则应该能够挂接到主事件循环以使其定期调用您的函数。 非线程方法确实会导致程序在函数挂起时被阻塞,而不是在函数调用之间。
最简单的方法是创build一个每60秒运行一次的后台线程。 一个简单的实现是:
class BackgroundTimer(Thread): def run(self): while 1: Time.sleep(60) # do something # ... SNIP ... # Inside your main thread # ... SNIP ... timer = BackgroundTimer() timer.start()
显然,如果“做某事”需要很长时间,则需要在睡眠声明中适应。 但这是一个很好的近似值。
我search了一下,发现了Python 电路框架,这使得可以等待
为特定的事件。
电路的.callEvent(self, event, *channels)
方法包含一个消息和挂起直到响应function,文档说:
将给定的事件触发到指定的通道并暂停执行,直到它被调度。 这个方法只能作为一个处理程序顶级执行级别的
yield
参数(例如“yield self.callEvent(event)
”)。 它有效地创build并返回一个将由主循环调用的生成器,直到事件被调度(参见:func:circuits.core.handlers.handler
)。
我希望你能find和我一样有用的:)
。/问候
如果你想调用“在时钟上”的方法(例如每小时一小时 ),你可以把下面的想法和你select的任何线程机制结合起来:
import time def wait(n): '''Wait until the next increment of n seconds''' x = time.time() time.sleep(n-(x%n)) print time.asctime()
我认为重复运行线程的正确方法是下一步:
import threading import time def f(): print("hello world") # your code here myThread.run() if __name__ == '__main__': myThread = threading.Timer(3, f) # timer is set to 3 seconds myThread.start() time.sleep(10) # it can be loop or other time consuming code here if myThread.is_alive(): myThread.cancel()
使用此代码,函数f在10秒的时间内每3秒执行一次。 最后线程运行被取消。
为什么不build立一个专门的线程,在其中放置一个简单的hibernate循环:
#!/usr/bin/env python import time while True: # Your code here time.sleep(60)