That’s par for the course in Python- everyone seems to have their own pattern.
Note: Skip ahead to “Set and forget…” if you don’t need to stop or interact with your long running task
In my case I use a pattern called
StoppableThread and another called
AsyncWorker which, when combined, give you nice copy and paste classes to handle most of the common use cases for threads- at least until it starts getting very application specific and complex.
They are as follows:
"""Basic Stoppable Thread Wrapper
Adds event for stopping the execution
loop and exiting cleanly."""
self.stop_event = threading.Event()
self.daemon = True
if not self.isAlive():
"""Basic thread wrapper class for asynchronously running functions
Return False from the worker function to abort loop."""
def __init__(self, todo):
self.todo = todo
while not self.stop_event.is_set():
# Explicitly check for False being returned
# from worker, IE: Don't allow None
if self.todo() is False:
In your case you might want to rewrite your 5 minute loop to be run by
AsyncWorker, which basically involves converting your
function which can be run over and over again. This is by no means essential, but it does mean - assuming what you’re doing allows - that you can stop this process before the 5 minute run time is up.
A simple example might be:
count = 0
count += 1
if count == 10:
worker = AyncWorker(count_to_ten)
AsyncWorker code should probably use
while not event.wait(some_sleep_amount) to delay, rather than
time.sleep() but this is a minor implementation detail you’ll only run into with more sophisticated uses of threads.
Set and forget…
If you dont want or need to stop your 5 minute task mid process, and if your task is sufficiently detacted from the rest of your code that you’re really just runnign something in the background, you can just spawn a thread and forget about it like so:
for x in range(100):
thread = threading.Thread(target=long_running_task)
In all cases your “thread” should have some kind of
time.sleep() becuase Python has a “global interpreter lock” that basically only allows one thread to access objects at a time. If you don’t give up the “GIL” manually to give other code a chance to run and interact with the objects it needs, you’ll run into all sorts of exciting problems!