I am trying to implement a heartbeat call that works in the background. How do I create a threaded on interval call of say every 30 seconds, which calls the following function:
self.mqConn.heartbeat_tick()
Also how would I stop this thread?
Many thanks.
Use the Python threading module to create a multi-threaded application. Use the Thread(function, args) to create a new thread. Call the start() method of the Thread class to start the thread. Call the join() method of the Thread class to wait for the thread to complete in the main thread.
With the help of the Schedule module, we can make a python script that will be executed in every given particular time interval. with this function schedule. every(5). minutes.do(func) function will call every 5 minutes.
Use a thread containing a loop
from threading import Thread
import time
def background_task():
while not background_task.cancelled:
self.mqConn.heartbeat_tick()
time.sleep(30)
background_task.cancelled = False
t = Thread(target=background_task)
t.start()
background_task.cancelled = True
Alternatively, you could subclass timer, to make cancelling easy:
from threading import Timer
class RepeatingTimer(Timer):
def run(self):
while not self.finished.is_set():
self.function(*self.args, **self.kwargs)
self.finished.wait(self.interval)
t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick)
t.start() # every 30 seconds, call heartbeat_tick
# later
t.cancel() # cancels execution
Or you could use the Timer class in the threading module:
from threading import Timer
def hello():
print "hello, world"
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
t.cancel() # cancels execution, this only works before the 30 seconds is elapsed
This will not start every x seconds, rather it delays the thread for execution in x seconds. But you can still put that in a loop and use t.is_alive() to see its status.
A quick followup to Eric's answer: you can't subclass Timer
in python 2, since it's actually a light function wrapper around the true class: _Timer
. If you do you'll get the issue that pops up in this post.
Using _Timer
instead fixes it:
from threading import _Timer
class RepeatingTimer(_Timer):
def run(self):
while not self.finished.is_set():
self.function(*self.args, **self.kwargs)
self.finished.wait(self.interval)
t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick)
t.start() # every 30 seconds, call heartbeat_tick
# later
t.cancel() # cancels execution
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With