如何创建非阻塞线程?

时间:2018-05-18 12:56:32

标签: python multithreading python-multithreading

我一直在尝试在python中使用Threads。我正在研究Pi硬件项目。

问题在于:

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

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

    print("Hello World")

我需要一个在 SINGLE 线程上反复运行相同功能的线程进程,而不会影响或延迟我的主程序。即当一个线程完成执行该功能时,再次运行它...但我的主要应该仍然是打印" Hello World"照常。

我找到了一种方法来阻止它崩溃,这就是坐下来等待"直到线程完成,然后再次启动。但是,这是一种阻塞方法,完全违背了线程化的目的。

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

    print("Hello World")

有什么建议吗?

4 个答案:

答案 0 :(得分:1)

您可以使用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.randint(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()

答案 1 :(得分:0)

来自setDaemon(True)班级的{p> threading.Thread https://docs.python.org/2/library/threading.html#threading.Thread.daemon

答案 2 :(得分:0)

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

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())。

答案 3 :(得分:0)

  

我需要一个在SINGLE线程上反复运行相同功能的线程进程

此代码段会创建一个不断调用myFunc()的单个帖子。

def threadMain() : 
    while True :
        myFunc()

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