+-
在Python中进行多线程处理时queue.Queue的正确实现
我正在学习 python,并编写了一些简单的脚本来为自己提供各种主题的实用示例.这样的脚本就是其中之一,它演示了如何将queue.Queue()与threading.Thread()结合使用来创建后台工作程序.它的行为虽然很奇怪.我进行了一些时间试验.仅使用一个线程即可完成您的预期工作…每个任务大约需要2秒钟,而完成20个任务大约需要40秒(实际上不到??).有了四个线程,它又可以像您期望的那样工作.它一次执行4个任务,因此大约需要10秒钟.那么,当我运行20个线程时,如何花费0.01秒(1 s.f.)—当然必须花费2秒?

这是代码:

import threading
from queue import Queue
import time

q = Queue()
tLock = threading.Lock()

def run() :

    while True :
        task = q.get()  
        print('Just finished task number',task)
        q.task_done()   
        time.sleep(2)

def main() :
    # worker threads are activated  
    for x in range(20) :
        t = threading.Thread(target=run)
        t.daemon = True
        t.start()
    #20 jobs are put in the queue   
    for x in range(1,21) :
        q.put(x)
    #waits until queue is empty and then continues
    q.join()

if __name__ == '__main__' :
    startTime = time.time()
    main()
    print('Time taken was', time.time() - startTime)
最佳答案
您实际上并没有阻止主线程的进度:

“适当的”(*)方法是通过加入所有线程来确保所有线程都已完成:

def main() :
    # keep reference to threads
    threads = [threading.Thread(target=run) for _ in range(20)]
    # start all threads
    for t in threads:
        t.start()

    #20 jobs are put in the queue   
    for x in range(1,21) :
        q.put(x)
    #waits until queue is empty and then continues
    q.join()
    # join all threads
    for t in threads:
        t.join()

*但是,这将无法工作,因为您的线程处于无限循环中,即使完成了任务也是如此.

因此,另一种方法是确保在报告任务之前先等待:

def run() :
    while True :
        task = q.get()  
        # simulate processing time *before* actual reporting
        time.sleep(2)
        print('Just finished task number',task)  
        q.task_done()

尽管如此,线程仍然处于阻塞状态.您应该拥有的是一条消息,告诉线程退出.就像是:

def run() :
    while True :
        task = q.get()
        if task == 'stop':
            break  
        # simulate processing time *before* actual reporting
        time.sleep(2)
        print('Just finished task number',task)  
        q.task_done()

现在只需告诉主线程为所有线程放置足够的停止消息即可最终退出其无限循环:

def main() :
    # keep reference to threads
    threads = [threading.Thread(target=run) for _ in range(20)]
    # start all threads
    for t in threads:
        t.start()

    #20 jobs are put in the queue   
    for x in range(1,21):
        q.put(x)

    for x in range(20):
        # stop all threads after tasks are done
        q.put('stop')

    # waits until queue is empty and then continues
    q.join()

    # join all threads
    for t in threads:
        t.join()

提示:不应使用“魔术数字”,例如20.在模块级别具有全局变量THREADS_COUNT,这样,当您要测试不同的配置时,只需更改一个位置.

点击查看更多相关文章

转载注明原文:在Python中进行多线程处理时queue.Queue的正确实现 - 乐贴网