Python 协程中的 IO 密集型任务和 CPU 密集型任务简单测试


由于 Python 中的协程是运行在一条线程中通过消息队列调控的,如果运行的线程堵塞了那么就会造成消息队列阻塞。为了避免这种情况的发生我们需要区分 IO 密集型任务和 CUP 密集型任务,在 IO 密集型任务中,协程发生阻塞后会在消息队列中挂起转而执行其它协程,而如果是 CUP 密集型任务则需要新开辟线程并放入执行以避免阻塞当前线程。

 1 """
 2     协程中 IO 密集型任务和 CPU 密集型任务的区别:
 3 
 4     协程碰到阻塞 IO 后会挂起继续执行下一个任务,在 IO 结束后恢复运行。
 5     而 CPU 密集型任务会阻塞整条消息队列(因为协程都是在一条线程里运行的),后果就是异步变成了同步。
 6 
 7     IO 密集型任务举例:请求网络(aiohttp)、读写文件(aiofiles)、操作数据库等,需要用到第三方库
 8     CPU 密集型任务举例:解析网页、数值计算等。
 9 
10     碰到 CUP 密集型任务为了防止队列阻塞,需要用到线程池,aio提供了相应的接口,可见官方文档。
11 """
12 import asyncio
13 import time
14 
15 async def work(n):
16     print(f'{n} is working.') # 这里会同时打印三条信息
17 
18     await asyncio.sleep(1) # 模拟 IO
19 
20     print(f'{n} is awaked') # 这里只会打印单条信息,因为下方是 CUP 密集型任务,会阻塞消息队列
21 
22     s = 0
23     for i in range(1000000): # 模拟 CPU 密集型任务
24         s += i
25 
26     print(f'{n} is done.')
27 
28     return s
29 
30 
31 async def main():
32     st = time.time()
33     tasks = [asyncio.create_task(work(i)) for i in range(3)] # 创建 3 个协程
34 
35     await asyncio.gather(*tasks) # 并发启动任务并等待任务结束
36 
37     # 取消任务
38     for task in tasks:
39         task.cancel()
40 
41     await asyncio.gather(*task, return_exceptions=True)
42 
43     print('Done {:.2f}'.format(time.time()-st))
44 
45 
46 if __name__ == '__main__':
47     asyncio.run(main())

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM