天天看點

Python程式設計:queue隊列queue隊列生産者消費者模型

queue隊列

先入先出隊列 first in first out

import queue

q1 = queue.Queue()

q1.put(1)
q1.put(2)
q1.put(3)

print(q1.get())
print(q1.get())
print(q1.get())
# 1 2 3      

後入先出隊列 last in first out

import queue

q2 = queue.LifoQueue()

q2.put(1)
q2.put(2)
q2.put(3)

print(q2.get())
print(q2.get())
print(q2.get())
# 3 2 1      

優先級隊列

import queue

q3 = queue.PriorityQueue()

q3.put((10, 1))
q3.put((9, 2))
q3.put((8, 3))

print(q3.get())
print(q3.get())
print(q3.get())
# (8, 3)  (9, 2)  (10, 1)      

生産者消費者模型

在并發程式設計中使用生産者和消費者模式能夠解決絕大多數并發問題。

該模式通過平衡生産線程和消費線程的工作能力來提高程式的整體處理資料的速度。

為什麼要使用生産者和消費者模式

線上程世界裡,生産者就是生産資料的線程,消費者就是消費資料的線程。

在多線程開發當中,如果生産者處理速度很快,而消費者處理速度很慢,

那麼生産者就必須等待消費者處理完,才能繼續生産資料。同樣的道理,

如果消費者的處理能力大于生産者,那麼消費者就必須等待生産者。

為了解決這個問題于是引入了生産者和消費者模式。

什麼是生産者消費者模式

生産者消費者模式是通過一個容器來解決生産者和消費者的強耦合問題。

生産者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,

是以生産者生産完資料之後不用等待消費者處理,直接扔給阻塞隊列,

消費者不找生産者要資料,而是直接從阻塞隊列裡取,阻塞隊列就相當于一個緩沖區,

平衡了生産者和消費者的處理能力。

執行個體代碼

import queue, threading, time

q = queue.Queue(maxsize=10)

def producer(name):
    count = 0
    while True:
        count += 1
        q.put("包子 %s" % count)
        print("%s 生産了一個包子" % name)
        time.sleep(2)

def consumer(name):
    while True:
        print("%s 得到了 %s" % (name, q.get()))

p1 = threading.Thread(target=producer, args=("生産者1",))
c1 = threading.Thread(target=consumer, args=("消費者1",))
c2 = threading.Thread(target=consumer, args=("消費者2",))

p1.start()
c1.start()
c2.start()      

阻塞隊列

import queue, threading, time

q = queue.Queue()

def producer(name):
    for i in range(5):
        q.put("包子 %s" % i)

    print("等待取走")
    q.join()  # 等待通知,全部取走則繼續
    print("全都取走了")


def consumer(name):
    while q.qsize() > 0:
        print("%s 得到了 %s" % (name, q.get()))
        q.task_done()  # 告知一次任務結束

p1 = threading.Thread(target=producer, args=("生産者1",))
p1.start()

c = consumer("消費者")
"""
等待取走
消費者 得到了 包子 0
消費者 得到了 包子 1
消費者 得到了 包子 2
消費者 得到了 包子 3
消費者 得到了 包子 4
全都取走了
"""