【python】生成器案例之基於0庫存的生產者消費者模型

【摘要】上一篇博文介紹了傳統的生產者消費者模型,共有三個元素要素(生產者、消費者、緩衝區)。傳統的生產者-消費者模型是一個線程寫消息,一個線程取消息,通過鎖機制控制隊列和等待,但一不小心就可能死鎖。
這篇博文介紹的基於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關鍵字。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章