1. 程式人生 > >python 多執行緒處理佇列

python 多執行緒處理佇列

轉載自: https://blog.csdn.net/u011655220/article/details/79037032

from threading import Thread
import time
import random
from queue import Queue
from collections import deque

#建立佇列,設定佇列最大數限制為3個
queue = Queue()

#生產者執行緒
class Pro_Thread(Thread):
    def run(self):
        #原材料準備,等待被生產
        tasks = deque(list(range(500)))
        global queue
        while True:
            try:
                #從原材料左邊開始生產
                task = tasks.popleft()
                queue.put(task)
                print("生產", task, "現在佇列數:", queue.qsize())

                #休眠隨機時間
                time.sleep(random.random())
            #如果原材料被生產完,生產執行緒跳出迴圈
            except IndexError:
                print("原材料已被生產完畢")
                break

#消費者執行緒
class Con_Thread(Thread):
    def __init__(self, i):
        super().__init__()
        self.id = i
    def run(self):
        global queue
        while True:
            if queue.not_empty:
                #通過get(),這裡已經將佇列減去了1
                task = queue.get()
                print("當前資料被")
                time.sleep(1)
                #這裡可能佇列數已經空了,但是消費者手裡還有正在消費的佇列
                #發出完成的訊號,不發的話,join會永遠阻塞,程式不會停止
                queue.task_done()
                print("消費", self.id)
            else:
                break

#r入口方法,主執行緒
def main():
    Pro_1 = Pro_Thread()
    #把生產執行緒列為守護執行緒,否則主執行緒結束之後不會銷燬該執行緒,程式不會停止,影響實驗結果
    Pro_1.setDaemon(True)
    #啟動執行緒
    Pro_1.start()

    for i in range(5):
        Con_i = Con_Thread(i)
        # 把兩個消費者執行緒列為守護執行緒,否則主執行緒結束之後不會銷燬該執行緒,程式不會停止,影響實驗結果
        Con_i.setDaemon(True)
        #啟動執行緒
        Con_i.start()
    global queue
    #這裡休眠一秒鐘,等到佇列有值,否則佇列建立時是空的,主執行緒直接就結束了,實驗失敗,造成誤導
    time.sleep(1)
    #接收訊號,主執行緒在這裡等待佇列被處理完畢後再做下一步
    queue.join()
    #給個標示,表示主執行緒已經結束
    print("主執行緒結束")

if __name__ == '__main__':
    main()