How to execute a function asynchronously every 60 seconds in Python?
I want to execute a function every 60 seconds on Python but I don't want to be blocked meanwhile.
How can I do it asynchronously?
import threading
import time
def f():
print("hello world")
threading.Timer(3, f).start()
if __name__ == '__main__':
f()
time.sleep(20)
With this code, the function f is executed every 3 seconds within the 20 seconds time.time. At the end it gives an error and I think that it is because the threading.timer has not been canceled.
How can I cancel it?
Thanks in advance!
You could try the threading.Timer class: 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()
The simplest way is to create a background thread that runs something every 60 seconds. A trivial implementation is:
class BackgroundTimer(Thread):
def run(self):
while 1:
Time.sleep(60)
# do something
# ... SNIP ...
# Inside your main thread
# ... SNIP ...
timer = BackgroundTimer()
timer.start()
Obviously, this if the "do something" takes a long time, you'll need to accommodate for it in your sleep statement. But this serves as a good approximation.
I googled around and found the Python circuits Framework, which makes it possible to wait
for a particular event.
The .callEvent(self, event, *channels)
method of circuits contains a fire and suspend-until-response functionality, the documentation says:
Fire the given event to the specified channels and suspend execution until it has been dispatched. This method may only be invoked as argument to a
yield
on the top execution level of a handler (e.g. "yield self.callEvent(event)
"). It effectively creates and returns a generator that will be invoked by the main loop until the event has been dispatched (see :func:circuits.core.handlers.handler
).
I hope you find it as useful as I do :)
./regards