我正在學習Python的線程模塊,並寫了下面的代碼,以幫助自己瞭解爲什麼Queue.join()在這裏是必需的?
from Queue import Queue
import threading
lock = threading.Lock()
MAX_THREADS = 8
q = Queue()
count = 0
# some i/o process
def io_process(x):
pass
# process that deals with shared resources
def shared_resource_process(x):
pass
def func():
global q, count
while not q.empty():
x = q.get()
io_process(x)
if lock.acquire():
shared_resource_process(x)
print '%s is processing %r' %(threading.currentThread().getName(), x)
count += 1
lock.release()
def main():
global q
for i in range(40):
q.put(i)
threads = []
for i in range(MAX_THREADS):
threads.append(threading.Thread(target=func))
for t in threads:
t.start()
for t in threads:
t.join()
print 'multi-thread done.'
print count == 40
if __name__ == '__main__':
main()
和輸出被困這樣的:
Thread-1 is processing 32
Thread-8 is processing 33
Thread-6 is processing 34
Thread-2 is processing 35
Thread-5 is processing 36
Thread-3 is processing 37
Thread-7 is processing 38
Thread-4 is processing 39
注意,在主)的打印(不這意味着一些線程掛起/阻塞?
然後我加入q.task_done()修改FUNC()方法:
if lock.acquire():
shared_resource_process(x)
print '%s is processing %r' %(threading.currentThread().getName(), x)
count += 1
q.task_done() # why is this necessary ?
lock.release()
,現在所有的線程終止如我所料,並得到正確的輸出:
Thread-6 is processing 36
Thread-4 is processing 37
Thread-3 is processing 38
Thread-7 is processing 39
multi-thread done.
True
Process finished with exit code 0
我讀Queue.Queue here的文檔,並看到task_done()與queue.join()一起工作,以確保處理隊列中的所有項目。但是因爲我沒有在main()中調用queue.join(),爲什麼在func()中需要task_done()?當我錯過task_done()代碼時,線程掛起/阻塞的原因是什麼?
謝謝您的回答,很明顯,真正幫助 – vansdev