1、理解python
若是線程裏每從隊列裏取一次,但沒有執行task_done(),則join沒法判斷隊列到底有沒有結束,在最後執行個join()是等不到結果的,會一直掛起。
能夠理解爲,每task_done一次 就從隊列裏刪掉一個元素,這樣在最後join的時候根據隊列長度是否爲零來判斷隊列是否結束,從而執行主線程。安全
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import time 5 from threading import Thread 6 from queue import Queue 7 8 tickets = 100 9 # 隊列中,能夠聽任意類型的數據,線程安全 10 tickets_queue = Queue(100) 11 # 聲明退出條件 12 exitFlag = False 13 14 15 class TicketsThread(Thread): 16 17 def __init__(self, thread_id, sell_tickets_queue): 18 super().__init__() 19 self.thread_id = thread_id 20 self.sell_tickets_queue = sell_tickets_queue 21 22 # 代碼在run中執行,run中完善功能 23 def run(self): 24 super().run() 25 global tickets 26 global exitFlag 27 while True: 28 # 線程退出的條件 29 if exitFlag: 30 break 31 32 # 獲取隊列中數據 33 # Queue特色,取出來,沒了 34 try: 35 tickets = self.sell_tickets_queue.get(block=False) 36 print('線程:--------%d--------已賣票:%d' % (self.thread_id, tickets)) 37 time.sleep(1) 38 # 通知隊列,任務結束 39 self.sell_tickets_queue.task_done() 40 except Exception as e: 41 pass 42 43 44 if __name__ == '__main__': 45 ''' 46 多個線程,執行同一個任務 47 100url,一個線程,能夠 48 10個線程,執行如今請求,優化 49 賣票,多線程 50 10個窗口幫助咱們賣票 51 ''' 52 for i in range(1, 101): 53 # 向隊列中放入100張票 54 tickets_queue.put(i) 55 56 # 建立10個線程,讓10個線程一塊兒執行買票 57 for i in range(1, 11): 58 # 建立賣票線程,而且啓動 59 my_thread = TicketsThread(i, tickets_queue) 60 # 啓動,線程中的run方法,就開始執行 61 my_thread.start() 62 63 # join():判斷隊列是否爲空,若是爲空,程序繼續向下執行,若是不爲空,繼續等待。(能夠理解爲隊列鎖) 64 tickets_queue.join() 65 exitFlag = True