Skip to main content
 首页 » 编程设计

python之发出队列中作业结束的信号

2025年05月04日8insus

这是来自 Python 文档的示例代码:

def worker(): 
    while True: 
        item = q.get() 
        do_work(item) 
        q.task_done() 
 
q = Queue() 
for i in range(num_worker_threads): 
     t = Thread(target=worker) 
     t.daemon = True 
     t.start() 
 
for item in source(): 
    q.put(item) 
 
q.join()       # block until all tasks are done 

我修改它以适合我这样的用例:

import threading 
from Queue import Queue 
 
max_threads = 10 
 
q = Queue(maxsize=max_threads + 2) 
 
def worker(): 
  while True: 
    task = q.get(1) 
    # do something with the task 
    q.task_done() 
 
for i in range(max_threads): 
  t = threading.Thread(target=worker) 
  t.start() 
 
for task in ['a', 'b', 'c']: 
  q.put(task) 
 
q.join() 

当我执行它时,调试器说所有作业都已执行,但 q.join() 似乎永远等待。我如何向工作线程发送一个信号,表明我已经发送了所有任务?

请您参考如下方法:

此过程未在 .join() 处完成,因为工作线程继续等待新的队列数据(阻塞 .get())

这是一个使用简单标志 finishUp 告诉工作人员退出的方法,我们在 .join() 完成后设置它 - 这意味着所有任务都已处理。我在 q.get() 调用中添加了一个超时,以允许它检查 finishUp 标志

import threading 
import queue 
 
max_threads = 5 
q = queue.Queue(maxsize=max_threads + 2) 
finishUp = False 
 
def worker(): 
    while True: 
        try: 
            task = q.get(block=True, timeout=1) 
            # do something with the task 
            print ("processing task for:"+str(task)) 
            q.task_done() 
        except Exception as ex: # we get this exception when queue is empty 
            if finishUp: 
                print ("thread finishing because processing is done") 
                return 
 
for i in range(max_threads): 
  t = threading.Thread(target=worker) 
  t.start() 
 
for task in ['a', 'b', 'c']: 
  q.put(task) 
 
print ("waiting on join") 
q.join() 
finishUp = True  # let the workers know that they can exit 
print ("finished") 

这会产生以下输出:

waiting on join 
processing task for:a 
processing task for:b 
processing task for:c 
finished 
thread finishing because processing is done 
thread finishing because processing is done 
thread finishing because processing is done 
thread finishing because processing is done 
thread finishing because processing is done 
 
Process finished with exit code 0