简体   繁体   中英

Running infinite loops using python multi threading

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
.
.
.

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 atmulti-processing for this

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM