如何创建非阻塞线程?

How can I create non-blocking threads?

我一直在尝试在 python 中使用线程。我正在做一个 Pi 硬件项目。

问题来了:

当我创建一个线程并像这样调用它时,循环会在旧线程完成之前不断创建新线程。因此,减慢程序速度...(打印 'threading.active_count' 显示 20 多个活动线程)。

while True:
    t4 = Thread(target = myFunc, args=())
    t4.start()

    print("Hello World")

我需要一个线程进程,它 运行 在 SINGLE 线程上一遍又一遍地执行相同的功能,而不影响或延迟我的主程序。即,当一个线程完成执行该函数时,运行 再次...但我的 main 仍应正常打印 "Hello World"。

我找到了一种方法来阻止它崩溃,那就是坐下来 "wait" 直到线程结束,然后重新开始。然而,这是一种阻塞方法,完全违背了线程化的目的。

while True:
    t4 = Thread(target = myFunc, args=())
    t4.start()
    t4.join()

    print("Hello World")

有什么建议吗?

setDaemon(True) 来自 threading.Thread class 更多此处 https://docs.python.org/2/library/threading.html#threading.Thread.daemon

创建一个委托线程 - 即按顺序 运行 您的其他线程的线程:

def delegate(*args):
    while True:
        t = Thread(target=myFunc, args=args) # or just call myFunc(*args) instead of a thread
        t.start()
        t.join()

t = Thread(target=delegate, args=())
t.start()
while True:
    print("Hello world!")

或者更好的是,将您的 myFunc() 重新设计为 运行 它在 while True: ... 循环中的逻辑,并且只启动线程一次。

如果您不在线程中执行任何有助于上下文切换的工作,我还建议您添加某种延迟(例如 time.sleep())。

I need a threading process that runs the same function over and over on a SINGLE thread

此代码段创建了一个连续调用 myFunc().

的线程
def threadMain() : 
    while True :
        myFunc()

t4 = Thread(target = threadMain, args=())
t4.start()

您可以使用 multiprocessing.pool.ThreadPool 来管理新线程的启动并限制它们并发执行的最大数量。

from multiprocessing.pool import ThreadPool
from random import randint
import threading
import time

MAX_THREADS = 5  # Number of threads that can run concurrently.
print_lock = threading.Lock()  # Prevent overlapped printing from threads.

def myFunc():
    time.sleep(random.uniform(0, 1))  # Pause a variable amount of time.
    with print_lock:
        print('myFunc')

def test():
    pool = ThreadPool(processes=MAX_THREADS)

    for _ in range(100):  # Submit as many tasks as desired.
        pool.apply_async(myFunc, args=())

    pool.close()  # Done adding tasks.
    pool.join()  # Wait for all tasks to complete.
    print('done')


if __name__ == '__main__':
    test()