Reputation: 1
So I've got a problem similar to this: Running infinite loops using threads in python
I want to create a number of threads (up to 50) which are running the same code at the same time, having an infinite while loop. There's no interaction between these threads. The practical idea behind this is that i have a string of WS2811 LEDs which I want to control independently with different color modes like blinking.
The problem I have with the similar question is, that I don't want to create 50 classes for each thread if they are all doing the same. I'd like to create these threads, based on one common class, with a for loop. The problem I encountered with this is that only one thread is in this infinite loop, while the other one not even starts. How do I fix this?
import threading
import time
class LEDManager(threading.Thread):
def __init__(self, id_manager):
threading.Thread.__init__(self)
self.id_manager = int(id_manager)
def initiate(id_manager):
while True:
print("Thread " + str(id_manager) + " blink on")
time.sleep(2)
print("Thread " + str(id_manager) + " blink off")
time.sleep(2)
def main():
thread_id = ("0", "1")
led_index = 0
thread_list = list()
for objs in thread_id:
thread = threading.Thread(target=LEDManager.initiate(led_index), args=(led_index,))
thread_list.append(thread)
time.sleep(1)
led_index += 1
for thread in thread_list:
thread.start()
if __name__ == "__main__":
main()
The output from the code above is:
Thread 0 blink on
Thread 0 blink off
Thread 0 blink on
Thread 0 blink off
.
.
.
Upvotes: 0
Views: 562
Reputation: 62093
Since you're deriving LEDManager
from threading.Thread
, it is a thread. Don't create new threadingThread
objects to run its member function! Just create instances of LEDManager
and start()
those:
import threading
import time
class LEDManager(threading.Thread):
def __init__(self, id_manager):
threading.Thread.__init__(self)
self.id_manager = int(id_manager)
def run(self):
while True:
print("Thread " + str(self.id_manager) + " blink on")
time.sleep(2)
print("Thread " + str(self.id_manager) + " blink off")
time.sleep(2)
def main():
thread_id = ("0", "1")
led_index = 0
thread_list = list()
for objs in thread_id:
thread = LEDManager(led_index)
thread_list.append(thread)
led_index += 1
for thread in thread_list:
thread.start()
time.sleep(1)
if __name__ == "__main__":
main()
(Credits to @stovfl)
The threading.Thread.run()
method is called automatically when the thread is start()
ed.
I also moved the one-second sleep to the start loop to get even interleaving of the threads' output, which I suspect is what you intended.
Upvotes: 0
Reputation: 4983
here is one way you can refactor the code to make it work
import threading
import time
class LEDManager(object):
def __init__(self):
pass
def initiate(self, idx):
while True:
print("Thread " + str(idx) + " blink on")
time.sleep(2)
print("Thread " + str(idx) + " blink off")
time.sleep(2)
def main():
thread_list = list()
l = LEDManager()
for i in range(50):
thread = threading.Thread(target=l.initiate, args=(i,))
thread_list.append(thread)
for thread in thread_list:
thread.start()
of course it could be written in much more best practice way, my suggestion is to look at greenlet
keep in mind the GIL won't give you real threading behaviour (truly parallel run) you can take a look at multi-processing for this
Upvotes: 0