[英]The correct implementation of queue.Queue when multithreading in Python
我正在學習python並編寫了一些簡單的腳本來給自己提供各種主題的實例。 其中一個是這個腳本,用於演示queue.Queue()如何與threading.Thread()一起使用來創建后台工作者。 雖然這很奇怪。 我跑了一些時間試驗。 只需要一個線程,就像你期望的那樣......每個任務花費大約2秒鍾(實際上只是在??)40秒內完成20個任務。 有四個線程,它會再次像您期望的那樣。 它一次完成4個任務,因此大約需要10秒。 那么當我運行20個線程時,地球如何需要0.01秒(1平方英尺) - 當然它必須花費2秒???
這是代碼:
import threading
from queue import Queue
import time
q = Queue()
tLock = threading.Lock()
def run() :
while True :
task = q.get()
print('Just finished task number',task)
q.task_done()
time.sleep(2)
def main() :
# worker threads are activated
for x in range(20) :
t = threading.Thread(target=run)
t.daemon = True
t.start()
#20 jobs are put in the queue
for x in range(1,21) :
q.put(x)
#waits until queue is empty and then continues
q.join()
if __name__ == '__main__' :
startTime = time.time()
main()
print('Time taken was', time.time() - startTime)
你實際上並沒有阻止主線程的進度:
“正確”(*)方法是通過連接所有線程來確保所有線程都已完成:
def main() :
# keep reference to threads
threads = [threading.Thread(target=run) for _ in range(20)]
# start all threads
for t in threads:
t.start()
#20 jobs are put in the queue
for x in range(1,21) :
q.put(x)
#waits until queue is empty and then continues
q.join()
# join all threads
for t in threads:
t.join()
*但是 ,這不會起作用,因為你的線程處於無限循環中,甚至完成任務。
另一種方法是確保在報告任務之前等待:
def run() :
while True :
task = q.get()
# simulate processing time *before* actual reporting
time.sleep(2)
print('Just finished task number',task)
q.task_done()
仍然,線程仍然被阻止。 你應該擁有的是給線程告訴他們退出的信息。 就像是:
def run() :
while True :
task = q.get()
if task == 'stop':
break
# simulate processing time *before* actual reporting
time.sleep(2)
print('Just finished task number',task)
q.task_done()
現在簡單地告訴主線程為所有線程放置足夠的停止消息以最終退出它們的無限循環:
def main() :
# keep reference to threads
threads = [threading.Thread(target=run) for _ in range(20)]
# start all threads
for t in threads:
t.start()
#20 jobs are put in the queue
for x in range(1,21):
q.put(x)
for x in range(20):
# stop all threads after tasks are done
q.put('stop')
# waits until queue is empty and then continues
q.join()
# join all threads
for t in threads:
t.join()
提示:您不應該使用“魔術數字”,例如20
。 在名為THREADS_COUNT
的模塊級別中有一個全局變量,因此當您要測試不同的配置時,只需要更改一個位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.