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才結束阻塞,繼續執行其他任務。