简体   繁体   English

使用 python 多线程运行无限循环

[英]Running infinite loops using python multi threading

So I've got a problem similar to this: Running infinite loops using threads in python所以我有一个类似的问题: 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.我想创建多个线程(最多 50 个)同时运行相同的代码,并具有无限的 while 循环。 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.这背后的实际想法是我有一串 WS2811 LED,我想用不同的颜色模式(如闪烁)独立控制它们。

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.我对类似问题的问题是,如果它们都在做同样的事情,我不想为每个线程创建 50 个类。 I'd like to create these threads, based on one common class, with a for loop.我想创建这些线程,基于一个常见的 class,带有一个 for 循环。 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:上面代码中的 output 是:

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当然它可以用更多的最佳实践方式来写,我的建议是看看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请记住, GIL不会为您提供真正的线程行为(真正的并行运行),您可以为此查看多处理

Since you're deriving LEDManager from threading.Thread , it is a thread.由于您从threading.Thread派生LEDManager ,因此它一个线程。 Don't create new threadingThread objects to run its member function!不要创建新的threadingThread对象来运行它的成员函数! Just create instances of LEDManager and start() those:只需创建LEDManagerstart()的实例:

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) (归功于@stovfl)

The threading.Thread.run() method is called automatically when the thread is start() ed. threading.Thread.run()方法在线程被start()编辑时自动调用。

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.我还将一秒钟的睡眠移到了开始循环,以使线程的 output 交错,我怀疑这是您的意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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