python3.6以上 asyncio模塊的異步編程模型 async await語法

這是python3.6以上版本的用法,本例是python3.7.2編寫
使用asyncio模塊的異步編程模型,生產這消費者,異步生產,用sleep來代替IO等待
使用async和await語法來進行描述
async關鍵字描述一個方法是異步函數(協程),是能夠被send()的,也是能夠被asyncio加入到協程池進行調度的
yield關鍵字表示在async描述的方法中定義一個出入點,至關於return,可是能夠在下一次函數被send()或者循環調用時做爲切入點繼續向下運行。
await關鍵字表示掛起等待的IO,函數內部後續運算會等待此處IO結束再運行,其餘協程函數會在此等待時使用CPU進行運行。

#生產這消費者模型,
#消費者到超市購買土豆和西紅柿
#須要買50個土豆和50個西紅柿
#當前貨架上,有5個土豆,5個西紅柿
#消費者開始拿取
#具體邏輯
# 一個一個拿東西
#從貨架拿土豆,一個一個的,當貨架上的土豆拿完了,去問土豆還有沒,觸發土豆工廠開始作土豆,隨機幾個,生產須要花費時間,
# 因此,業務上認定爲是1秒生產一個,所有生產完成才上架,這裏簡化爲獲取時間與生產個數相同,一秒生產一個,這裏不是重點,重點是體現了上架須要時間。
#在等待生產上架土豆的過程當中,開始拿取西紅柿,
#西紅柿也是一樣道理,等待西紅柿時去拿取土豆,如此往復,若是都在未上架,則等待

程序代碼以下:
import asyncio,random

class Potato:
    '''定義一個土豆生產廠家'''
    @classmethod
    def make(cls, num, *args, **kws):
        potatos = []
        print("開始製造 %s 個土豆" % num)
        for i in range(num):
            print("製造第[%s]土豆"%i)
            potatos.append(cls.__new__(cls, *args, **kws))
        return potatos

# 先生成5個土豆而且上架
all_potatos = Potato.make(5)

class Tomatos:
    '''定義一個西紅柿生產廠家'''
    @classmethod
    def make(cls, num, *args, **kws):
        totatos = []
        print("開始製造 %s 個西紅柿" % num)
        for i in range(num):
            print("製造第[%s]西紅柿" % i)
            totatos.append(cls.__new__(cls, *args, **kws))

        return totatos

all_tomatos = Tomatos.make(5)

async def ask_for_potato():
    '''詢問土豆,製造的土豆,上架土豆,忽略寫法,直接描述了上架全程所需時間'''
    make_num=random.randint(1, 10)
    print("開始進行掛起,生產%s個土豆"%make_num)
    print("接下來遇到IO等待,運行其餘協程函數")
    await asyncio.sleep(make_num)
    all_potatos.extend(Potato.make(make_num))
    print("已經完成%s個土豆的生產"%make_num)

async def take_potatos(num):
    '''從貨架拿取土豆'''
    count = 0
    while True:
        if len(all_potatos) == 0:
            print("開始進行掛起,上架土豆")
            await ask_for_potato()
        potato = all_potatos.pop()
        yield potato
        count += 1
        if count == num:
            break

async def buy_potatos():
    '''購買土豆,放在本身的籃子裏,一共拿去50個,描述了一個需求,並開始動做'''
    bucket = []
    async for p in take_potatos(50):
        bucket.append(p)
        print(f'取到土豆: {id(p)}...')

async def ask_for_tomatos():
    '''詢問西紅柿,製造的西紅柿,上架西紅柿,忽略寫法,直接描述了上架全程所需時間'''
    make_num=random.randint(1, 10)
    print("開始進行掛起,生產%s個西紅柿" % make_num)
    print("接下來遇到IO等待,運行其餘協程函數")
    await asyncio.sleep(make_num)
    all_tomatos.extend(Tomatos.make(make_num))
    print("已經完成%s個西紅柿的生產"%make_num)

async def take_tomatos(num):
    '''從貨架拿取西紅柿'''
    count = 0
    while True:
        if len(all_tomatos) == 0:
            print("開始進行掛起,上架西紅柿")
            await ask_for_tomatos()
        potato = all_tomatos.pop()
        yield potato
        count += 1
        if count == num:
            break
async def buy_tomatos():
    '''購買西紅柿,放在本身的籃子裏,一共拿去50個,描述了一個需求,並開始動做'''
    bucket = []
    async for p in take_tomatos(50):
        bucket.append(p)
        print(f'取到西紅柿: {id(p)}...')

def main():
    import asyncio
    loop = asyncio.get_event_loop()
    res = loop.run_until_complete(asyncio.wait([buy_potatos(), buy_tomatos()]))
    loop.close()


if __name__=="__main__":
    import time
    begin_time=time.time()
    main()
    end_time=time.time()
    print("耗時是:%s秒"%(end_time-begin_time))

 

運行結果:html

開始製造 5 個土豆
製造第[0]土豆
製造第[1]土豆
製造第[2]土豆
製造第[3]土豆
製造第[4]土豆
開始製造 5 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
製造第[2]西紅柿
製造第[3]西紅柿
製造第[4]西紅柿
取到西紅柿: 140473681858176...
取到西紅柿: 140473681857504...
取到西紅柿: 140473681857448...
取到西紅柿: 140473681857560...
取到西紅柿: 140473681857168...
開始進行掛起,上架西紅柿
開始進行掛起,生產7個西紅柿
接下來遇到IO等待,運行其餘協程函數
取到土豆: 140473681857112...
取到土豆: 140473681855768...
取到土豆: 140473681855712...
取到土豆: 140473743063304...
取到土豆: 140473743062688...
開始進行掛起,上架土豆
開始進行掛起,生產7個土豆
接下來遇到IO等待,運行其餘協程函數
開始製造 7 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
製造第[2]西紅柿
製造第[3]西紅柿
製造第[4]西紅柿
製造第[5]西紅柿
製造第[6]西紅柿
已經完成7個西紅柿的生產
取到西紅柿: 140473681877928...
取到西紅柿: 140473681877872...
取到西紅柿: 140473681877816...
取到西紅柿: 140473681877760...
取到西紅柿: 140473681877592...
取到西紅柿: 140473681877648...
取到西紅柿: 140473681877704...
開始進行掛起,上架西紅柿
開始進行掛起,生產10個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 7 個土豆
製造第[0]土豆
製造第[1]土豆
製造第[2]土豆
製造第[3]土豆
製造第[4]土豆
製造第[5]土豆
製造第[6]土豆
已經完成7個土豆的生產
取到土豆: 140473681878320...
取到土豆: 140473681878264...
取到土豆: 140473681878208...
取到土豆: 140473681878152...
取到土豆: 140473681878096...
取到土豆: 140473681878040...
取到土豆: 140473681877984...
開始進行掛起,上架土豆
開始進行掛起,生產9個土豆
接下來遇到IO等待,運行其餘協程函數
開始製造 9 個土豆
製造第[0]土豆
製造第[1]土豆
製造第[2]土豆
製造第[3]土豆
製造第[4]土豆
製造第[5]土豆
製造第[6]土豆
製造第[7]土豆
製造第[8]土豆
已經完成9個土豆的生產
取到土豆: 140473681878824...
取到土豆: 140473681878768...
取到土豆: 140473681878712...
取到土豆: 140473681878656...
取到土豆: 140473681878600...
取到土豆: 140473681878544...
取到土豆: 140473681878488...
取到土豆: 140473681878432...
取到土豆: 140473681878376...
開始進行掛起,上架土豆
開始進行掛起,生產9個土豆
接下來遇到IO等待,運行其餘協程函數
開始製造 10 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
製造第[2]西紅柿
製造第[3]西紅柿
製造第[4]西紅柿
製造第[5]西紅柿
製造第[6]西紅柿
製造第[7]西紅柿
製造第[8]西紅柿
製造第[9]西紅柿
已經完成10個西紅柿的生產
取到西紅柿: 140473670754712...
取到西紅柿: 140473670754656...
取到西紅柿: 140473670754600...
取到西紅柿: 140473670754544...
取到西紅柿: 140473670754488...
取到西紅柿: 140473670754432...
取到西紅柿: 140473670754376...
取到西紅柿: 140473681878992...
取到西紅柿: 140473681878936...
取到西紅柿: 140473681878880...
開始進行掛起,上架西紅柿
開始進行掛起,生產7個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 7 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
製造第[2]西紅柿
製造第[3]西紅柿
製造第[4]西紅柿
製造第[5]西紅柿
製造第[6]西紅柿
已經完成7個西紅柿的生產
取到西紅柿: 140473670755104...
取到西紅柿: 140473670755048...
取到西紅柿: 140473670754992...
取到西紅柿: 140473670754936...
取到西紅柿: 140473670754880...
取到西紅柿: 140473670754824...
取到西紅柿: 140473670754768...
開始進行掛起,上架西紅柿
開始進行掛起,生產7個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 9 個土豆
製造第[0]土豆
製造第[1]土豆
製造第[2]土豆
製造第[3]土豆
製造第[4]土豆
製造第[5]土豆
製造第[6]土豆
製造第[7]土豆
製造第[8]土豆
已經完成9個土豆的生產
取到土豆: 140473670755608...
取到土豆: 140473670755552...
取到土豆: 140473670755496...
取到土豆: 140473670755440...
取到土豆: 140473670755384...
取到土豆: 140473670755328...
取到土豆: 140473670755272...
取到土豆: 140473670755216...
取到土豆: 140473670755160...
開始進行掛起,上架土豆
開始進行掛起,生產8個土豆
接下來遇到IO等待,運行其餘協程函數
開始製造 7 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
製造第[2]西紅柿
製造第[3]西紅柿
製造第[4]西紅柿
製造第[5]西紅柿
製造第[6]西紅柿
已經完成7個西紅柿的生產
取到西紅柿: 140473670756000...
取到西紅柿: 140473670755944...
取到西紅柿: 140473670755888...
取到西紅柿: 140473670755832...
取到西紅柿: 140473670755776...
取到西紅柿: 140473670755720...
取到西紅柿: 140473670755664...
開始進行掛起,上架西紅柿
開始進行掛起,生產1個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 1 個西紅柿
製造第[0]西紅柿
已經完成1個西紅柿的生產
取到西紅柿: 140473670756056...
開始進行掛起,上架西紅柿
開始進行掛起,生產4個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 8 個土豆
製造第[0]土豆
製造第[1]土豆
製造第[2]土豆
製造第[3]土豆
製造第[4]土豆
製造第[5]土豆
製造第[6]土豆
製造第[7]土豆
已經完成8個土豆的生產
取到土豆: 140473670756504...
取到土豆: 140473670756448...
取到土豆: 140473670756392...
取到土豆: 140473670756336...
取到土豆: 140473670756280...
取到土豆: 140473670756224...
取到土豆: 140473670756168...
取到土豆: 140473670756112...
開始進行掛起,上架土豆
開始進行掛起,生產5個土豆
接下來遇到IO等待,運行其餘協程函數
開始製造 4 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
製造第[2]西紅柿
製造第[3]西紅柿
已經完成4個西紅柿的生產
取到西紅柿: 140473670756728...
取到西紅柿: 140473670756672...
取到西紅柿: 140473670756616...
取到西紅柿: 140473670756560...
開始進行掛起,上架西紅柿
開始進行掛起,生產1個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 1 個西紅柿
製造第[0]西紅柿
已經完成1個西紅柿的生產
取到西紅柿: 140473670756784...
開始進行掛起,上架西紅柿
開始進行掛起,生產2個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 5 個土豆
製造第[0]土豆
製造第[1]土豆
製造第[2]土豆
製造第[3]土豆
製造第[4]土豆
已經完成5個土豆的生產
取到土豆: 140473670757064...
取到土豆: 140473670757008...
取到土豆: 140473670756952...
取到土豆: 140473670756896...
取到土豆: 140473670756840...
開始進行掛起,上架土豆
開始進行掛起,生產10個土豆
接下來遇到IO等待,運行其餘協程函數
開始製造 2 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
已經完成2個西紅柿的生產
取到西紅柿: 140473670757176...
取到西紅柿: 140473670757120...
開始進行掛起,上架西紅柿
開始進行掛起,生產9個西紅柿
接下來遇到IO等待,運行其餘協程函數
開始製造 10 個土豆
製造第[0]土豆
製造第[1]土豆
製造第[2]土豆
製造第[3]土豆
製造第[4]土豆
製造第[5]土豆
製造第[6]土豆
製造第[7]土豆
製造第[8]土豆
製造第[9]土豆
已經完成10個土豆的生產
取到土豆: 140473670757736...
取到土豆: 140473670757680...
取到土豆: 140473670757624...
取到土豆: 140473670757568...
取到土豆: 140473670757512...
取到土豆: 140473670757456...
取到土豆: 140473670757400...
開始製造 9 個西紅柿
製造第[0]西紅柿
製造第[1]西紅柿
製造第[2]西紅柿
製造第[3]西紅柿
製造第[4]西紅柿
製造第[5]西紅柿
製造第[6]西紅柿
製造第[7]西紅柿
製造第[8]西紅柿
已經完成9個西紅柿的生產
取到西紅柿: 140473681878152...
取到西紅柿: 140473681878208...
取到西紅柿: 140473681878264...
取到西紅柿: 140473681878320...
取到西紅柿: 140473743062688...
取到西紅柿: 140473743063304...
耗時是:48.02546787261963秒

 

參考資料:python

https://www.cnblogs.com/dhcn/p/9032461.html編程

相關文章
相關標籤/搜索