我想在Python上每60秒执行一次函数,但我不希望同时被阻止。
我该如何异步进行?
import threading
import time
def f():
print("hello world")
threading.Timer(3, f).start()
if __name__ == '__main__':
f()
time.sleep(20)
使用此代码,函数f在20秒time.time内每3秒执行一次。 最后它给出了一个错误,我认为这是因为threading.timer还没有被取消。
如何取消?
提前致谢!
答案 0 :(得分:95)
您可以尝试使用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()
答案 1 :(得分:2)
最简单的方法是创建一个每60秒运行一次的后台线程。一个简单的实现是:
class BackgroundTimer(Thread):
def run(self):
while 1:
Time.sleep(60)
# do something
# ... SNIP ...
# Inside your main thread
# ... SNIP ...
timer = BackgroundTimer()
timer.start()
显然,如果“做某事”需要很长时间,你需要在睡眠声明中适应它。但这可以作为一个很好的近似值。
答案 2 :(得分:2)
这取决于你实际上想要做的事情。线程是最常用和最不受欢迎的方式;你应该知道使用它时线程的问题:并非所有(非Python)代码都允许同时从多个线程进行访问,线程之间的通信应该使用线程安全的数据结构来完成,比如Queue.Queue
,你赢了“能够从它外部中断线程,并在线程仍在运行时终止程序可能导致挂起的解释器或虚假的回溯。
通常有一种更简单的方法。如果您在GUI程序中执行此操作,请使用GUI库的计时器或事件功能。所有的GUI都有这个。同样,如果您正在使用其他事件系统,如Twisted或其他服务器进程模型,您应该能够挂钩到主事件循环,以使其定期调用您的函数。非线程方法会导致程序在函数挂起时被阻止,但不会在函数调用之间被阻止。
答案 3 :(得分:2)
我用Google搜索并找到了Python circuits框架,这样就可以等待 对于特定事件。
电路的.callEvent(self, event, *channels)
方法包含一个fire和suspend-until-response功能,文档说:
将给定事件触发到指定通道并暂停执行 直到它被派遣。此方法只能作为调用方法 在处理程序的最高执行级别上的
yield
的参数(例如 “yield self.callEvent(event)
”)。它有效地创造和回报 主循环将调用的生成器,直到事件发生 被派遣(见:func:circuits.core.handlers.handler
)。
我希望你发现它像我一样有用:) ./regards
答案 4 :(得分:1)
如果你想在时钟"上调用方法" (例如,每小时小时),您可以将以下想法与您选择的任何线程机制集成:
import time
def wait(n):
'''Wait until the next increment of n seconds'''
x = time.time()
time.sleep(n-(x%n))
print time.asctime()
答案 5 :(得分:1)
我认为重复运行线程的正确方法是下一步:
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秒time.sleep(10)内每3秒执行一次。最后,线程的运行被取消。
答案 6 :(得分:0)
为什么不创建专用线程,在其中放置一个简单的睡眠循环:
#!/usr/bin/env python
import time
while True:
# Your code here
time.sleep(60)