Queue.task_done() 与 Queue.join()
使用queue一般用于在线程间传递数据,通过queue.put()与queue.get()来获取任务数据,通常需要在任务执行完成之后进行下一步操作,如果单纯靠判断queue是否为空不能判断任务是否结束,queue为空,但任务可能还在执行中,所以需要queue.join()来阻塞等待,而queue.task_done()来告诉queue.join()任务是否结束。
比如:
import logging
import queue
import threading
import time
items_queue = queue.Queue()
running = False
def items_queue_worker():
while running:
try:
item = items_queue.get(timeout=0.01)
if item is None:
continue
try:
process_item(item)
finally:
items_queue.task_done()
except queue.Empty:
pass
except:
logging.exception('error while processing item')
def process_item(item):
print('processing {} started...'.format(item))
time.sleep(0.5)
print('processing {} done'.format(item))
if __name__ == '__main__':
running = True
worker_threads = 10
thread_list = []
for _ in range(worker_threads):
t = threading.Thread(target=items_queue_worker)
t.start()
thread_list.append(t)
for i in range(100):
items_queue.put(i)
items_queue.join()
print('all task done')
for t in thread_list:
print(t.isAlive())
上面的代码,如果没有items_queue.task_done()则join阻塞,'all task done'以及下面判断线程是否alive永远不会被打印。
Queue.join()与thread.join()
在上面join等待结束,打印all task done之后,t.isAlive的结果为True,此时线程是仍旧运行的,而thread.join()是在线程结束isAlive结果为False才结束阻塞,继续执行其他任务。