I'm currently experimentating around with threading.Timer, and somehow I'm not doing very well.. My goal is to run hundreds of functions, repeating all the time. The problem is, that the usage of my RAM is growing and growing and growing, until the process stops.
This is how my code looks like:
from threading import Timer
class Foo:
def __init__(self, number):
self.number = number
self.timer = Timer(1, self.print_number)
self.timer.start()
def print_number(self):
print "Number: %s"%self.number
self.repeat()
def repeat(self):
self.timer.cancel()
#self.timer.join()
#time.sleep(1)
self.timer = Timer(3, self.print_number)
self.timer.start()
for x in range(1, 300):
Foo(x)
So, I've read that I can terminate a thread using .join() method after .cancel().
But when I do this I'm getting a RuntimeError: (cannot join current thread)
.
On a similar topic I've read that I can use time.sleep after .cancel() to terminate a thread,
but that does nothing to the thread for me.
My questions: How can I properly terminate the threads in this code example and how can I stop the script from using more and more RAM, or am I doing something terribly wrong?
Sorry if I'm re-asking a question that has been asked already many times, but I'm searching and trying for hours and couldn't find a solution yet.
Thanks in advance.
Something like this? Just have a break condition in the loop. The join at the end just makes sure all threads finish before moving forward. I use this often with a Queue (you can find samples, Queue Work Task pattern or some similar search).
Alternatively, I use apscheduler when I just need things to run on a timer or some cron-like functionality.
import threading
import time
WORKERS = 300
class Worker(threading.Thread):
def __init__(self, number):
self.number = number
threading.Thread.__init__(self)
def run(self):
while 1:
if self.number > 300:
break
print "Number: %s"%self.number
self.number += 1
time.sleep(3)
workers = []
for i in range(WORKERS):
w = Worker(100)
workers.append(w)
w.start()
for w in workers:
w.join()