2

下面是從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()似乎永遠等待。我如何向已發送所有任務的工作線程發送信號?

+0

最近可能的打印錯誤是:當循環變量爲'tasks'時,是否打算將'task'放入隊列?我不這麼認爲...... –

+0

是的,一個錯字。謝謝,我編輯了它。 – d33tah

+0

排隊包含thread.exit()的任務嗎? –

回答

1

q.join()實際返回。你可以在q.join()行後面加print("done")來測試。

.... 
q.join() 
print('done') 

那麼,它爲什麼不結束程序? 因爲默認情況下,線程是非守護線程。

可以使用<thread_object>.daemon = True

for i in range(max_threads): 
    t = threading.Thread(target=worker) 
    t.daemon = True # <--- 
    t.start() 

設置線程作爲守護線程根據threading module documentation

守護

一個布爾值,指示線程是否是守護線程 (真)或不(假)。這必須在調用start()之前設置,否則會引發RuntimeError 。它的初始值是從 繼承的創建線程;主線程不是守護線程,因此在主線程中創建的所有線程都默認爲守護進程= False。

當沒有活動的非守護進程線程 離開時,整個Python程序將退出。

版本2.6中的新功能。

+0

我實際上在一段時間後注意到它,將它與文檔中的代碼進行比較。謝謝! ;) – d33tah

+0

當然,對不起,我以爲我已經做到了。 – d33tah

+0

在這個例子中,守護進程工作線程在主Python進程終止之後永遠活着嗎?或者他們以某種方式清理? –