❝
上次的关于进程、线程和协程的文章,很多粉丝留言表示想看协程的实际案例。
❞
❝
那么今天就来结合代码实际讲一个协程的实际应用。
在此之前,我希望大家能已经理解什么是串行、并行和并发的概念。如果你还不知道这三者的区别请前往Python三分钟第131篇复习学习。
❞
普通函数
定义一个洗衣服函数,洗衣服过程时间为2秒。
睡眠
import time def wash_clothes(): time.sleep(2) # 洗衣服 def run(): for i in range(20): wash_clothes() print(f"衣服洗好了!当前时间:{time.time()}") if __name__ == '__main__': run()
运行结果:
衣服洗好了!当前时间:1659618457.003896 衣服洗好了!当前时间:1659618459.005437 衣服洗好了!当前时间:1659618461.0056782 衣服洗好了!当前时间:1659618463.010311 衣服洗好了!当前时间:1659618465.013951 衣服洗好了!当前时间:1659618467.018253 衣服洗好了!当前时间:1659618469.022136 衣服洗好了!当前时间:1659618471.022881 衣服洗好了!当前时间:1659618473.023118 衣服洗好了!当前时间:1659618475.027102 衣服洗好了!当前时间:1659618477.030786 衣服洗好了!当前时间:1659618479.032495 衣服洗好了!当前时间:1659618481.037195 衣服洗好了!当前时间:1659618483.040722 衣服洗好了!当前时间:1659618485.041149 衣服洗好了!当前时间:1659618487.046405 衣服洗好了!当前时间:1659618489.0484421 衣服洗好了!当前时间:1659618491.050224 衣服洗好了!当前时间:1659618493.055479 衣服洗好了!当前时间:1659618495.0585659
我们可以看出,函数间隔2秒多一点点输出一次时间。
协程函数
注意代码中注释
import time import asyncio # 异步函数定义需要在def前加async前缀 async def wash_clothes(): # sleep也需要使用协程专用的模块支持,同步的库不能在异步中使用 asyncio.sleep(2) print(f"衣服洗好了!当前时间:{time.time()}") def run(): for i in range(20): # 将协程函数注册到loop(循环事件)中 loop.run_until_complete(wash_clothes()) # 创建一个协程loop(循环事件)中 loop = asyncio.get_event_loop() if __name__ =='__main__': run()
运行结果:
衣服洗好了!当前时间:1659619085.0939178 衣服洗好了!当前时间:1659619085.094379 衣服洗好了!当前时间:1659619085.095523 衣服洗好了!当前时间:1659619085.095926 衣服洗好了!当前时间:1659619085.097046 衣服洗好了!当前时间:1659619085.0985332 衣服洗好了!当前时间:1659619085.099058 衣服洗好了!当前时间:1659619085.099848 衣服洗好了!当前时间:1659619085.101115 衣服洗好了!当前时间:1659619085.101917 衣服洗好了!当前时间:1659619085.1026182 衣服洗好了!当前时间:1659619085.103351 衣服洗好了!当前时间:1659619085.1034582 衣服洗好了!当前时间:1659619085.1035311 衣服洗好了!当前时间:1659619085.1042402 衣服洗好了!当前时间:1659619085.1052392 衣服洗好了!当前时间:1659619085.106337 衣服洗好了!当前时间:1659619085.106577 衣服洗好了!当前时间:1659619085.107519 衣服洗好了!当前时间:1659619085.108191
从运行结果看出,20桶衣服几乎在同0.1秒内洗完了。
大致过程
定义协程函数;创建协程循环事件;将已定义的协程函数注册到协程循环事件中;启动协程循环事件。❝
重点:协程函数内不能使用同步的函数或模块,否则将不会被异步运行。
❞
上一篇Python我提了协程执行的过程就像,“一个人启动一台洗衣机后,马上去使用第二台洗衣机,再第三台...第四台...第十台”。
「当洗衣机启动后的状态就等于是挂起了」
然后协程马上去启动下一台洗衣机...一直到结束。
后记
在某种意义上说,处理IO密集型任务协程的速度会高于多线程,因为线程的创建和销毁需要消耗更多资源。
如果将这个大杀器用于 爬虫,那不是速度要上天了?
是的,协程爬虫超猛。以前亲测比scrapy要快。
下期将从两个话题中选出一个:
什么是IO密集型任务和计算密集型任务?协程爬虫其他(写上内容)