什麼是生產者消費者模式
在軟件開發過程中,經常會遇到這樣的情景:
某些模塊負責生產數據,這些數據由其他模塊來負責處理(此處的模塊可能是:函數、線程、進程等)。產生數據的模塊稱爲生產者,而處理數據的模塊稱爲消費者。在生產者與消費者之間的緩衝區稱之爲倉庫。生產者負責往倉庫運輸商品,而消費者負責從倉庫裏取出商品,這就構成了生產者消費者模式。
結構圖:
舉個栗子:
假如珍妮要寄一封信,大致過程如下
1、珍妮把信寫好 —— 相當於生產者生產數據
2、珍妮把信放入郵箱 —— 相當於生產者把數據放入緩衝區
3、郵遞員把信從郵箱取出,做相應處理 —— 相當於消費者把數據取出緩衝區,處理數據
生產者消費者模式優點
1、解耦
假設生產者和消費者分別是兩個線程。如果讓生產者直接調用消費者的某個方法,那麼生產者對於消費者就會產生依賴(也就是耦合)。如果未來消費者的代碼發生變化,可能會影響到生產者的代碼。而如果兩者都依賴於某個緩衝區,兩者之間不直接依賴,耦合也就相應降低了。
2、併發
由於生產者與消費者是兩個獨立的併發體,他們之間是用緩衝區通信的,生產者只需要往緩衝區裏丟數據,就可以繼續生產下一個數據,而消費者只需要從緩衝區拿數據即可,這樣就不會因爲彼此的處理速度而發生阻塞。
3、忙閒不均
當生產者製造數據快的時候,消費者來不及處理,未處理的數據可以暫時存在緩衝區中,慢慢處理掉。而不至於因爲消費者的性能造成數據丟失或影響生產者生產。
下面用代碼實現一下:
代碼演示:
from queue import Queue
import threading
import time
#創建隊列
q = Queue(10)
def producer(name):
"""生產者"""
count = 1 # 給生產者的信計數
while True:
q.join() #等待task_done()發送信號
q.put(count)
print("%s正在寫第%d封信"%(name,count))
count += 1
time.sleep(0.1)
def customer(name):
"""消費者"""
count = 1
while True:
x = q.get()
print("%s正在取第%d封信"%(name,x))
count += 1
q.task_done() #取完後發送信號
time.sleep(1)
if __name__ == '__main__':
t1 = threading.Thread(target=producer,args=("珍妮",))
t2 = threading.Thread(target=customer,args=("郵遞員",))
t1.start()
t2.start()
運行結果:
今天就寫這裏