python3.6以上 asyncio模

发布时间:2019-05-12 19:12:04编辑:auto阅读(1842)

    这是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))

     

    运行结果:

    开始制造 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秒

     

    参考资料:

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

关键字

上一篇: python第十二周:MySql

下一篇: 进程池