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))
运行结果:
开始制造 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