【摘要】上一篇博文介紹了傳統的生產者消費者模型,共有三個元素要素(生產者、消費者、緩衝區)。傳統的生產者-消費者模型是一個線程寫消息,一個線程取消息,通過鎖機制控制隊列和等待,但一不小心就可能死鎖。
這篇博文介紹的基於0庫存的生產者消費者模型,是沒有緩衝區這個要素,改用協程(yield),生產者生產好後,直接通過yield跳轉到消費者開始執行,待消費者執行完畢後,切換回生產者繼續生產,效率極高。
代碼如下:
import time
def Consumer(name):
"""消費者"""
want_buy = input("請輸入購買物品:")
print("[%s]需要購買%s" %(name, want_buy))
while True:
# 將yield後面的need_produce發送給生產者, 生產者獲取生產的信息
goodsname = yield want_buy
print("[%s]購買%s成功" %(name, goodsname))
def Prodcder(name):
"""生產者"""
# []生成一個列表, 列表裏面是3個生成器(Consumer)
# ()生成一個生成器, 生成器裏面是3個生成器(Consumer)
consumers = (Consumer("消費者%s" %(i+1)) for i in range(3))
for consumer in consumers:
# next方法的返回值就是Consumer裏面yield後面跟的值;
need_produce = next(consumer)
print("工程師[%s]正在生產%s" %(name, need_produce))
time.sleep(1)
print("工程師[%s]生產%s成功" % (name, need_produce))
# 將生產好的數據發送給消費者
consumer.send(need_produce)
def main():
Prodcder("potizo")
main()
執行效果:
代碼執行流程:
-
Producer(“potizo”)
調用Producer這個函數,進入函數體 -
consumers = (Consumer(“消費者%s” %(i+1)) for i in range(3))
得到一個名爲consumers的生成器,這個生成器中包含三個生成器 -
for consumer in consumers
通過for循環迭代生成器,依次得到這個三個生成器 -
need_produce = next(consumer)
每得到一個生成器,就用next方法調用這個生成器,進入生成器consumer代碼中執行 -
want_buy = input(“請輸入購買物品:”)
用want_buy變量接收用戶輸入的內容
print("[%s]需要購買%s" %(name, want_buy))並打印 -
goodsname = yield want_buy
再繼續執行時,遇到yield關鍵字。這個生成器中的代碼停止執行,並將yield關鍵字後面的內容返回給next調用生成器那一行代碼
need_produce = next(consumer) 用need_produce變量接收返回來的值 -
print(“工程師[%s]正在生產%s” %(name, need_produce))
time.sleep(1)
print(“工程師[%s]生產%s成功” % (name, need_produce))
打印上述內容 -
consumer.send(need_produce)
生產好後,將內容通過send方法傳入consumer這個生成器,執行consumer生成器中的代碼。由於是用send方法,所以將變量need_produce傳給生成器中上一個yield之前的變量goodsname,並繼續執行後續代碼,直至遇到yield關鍵字。