14. Asyncio实现并发
14.1 Asyncio简介
多线程已经可以带来较大的效率提升,那么我们还需要asyncio的原因是:
- 多线程运行过程容易被打断,有可能出现race condition的情况
- 线程切换本身存在一定的消耗,若I/O操作非常heavy,多线程很有可能满足不了高效率、高质量的需求
sync和async的概念区分:
- sync即同步,指操作一个接一个地执行,下一个操作必须等上一个操作完成后才能执行
- async即异步,指不同的操作可以交替执行,如果其中某个操作被block了,程序并不会等待,而是会找出可执行的操作继续执行
14.2 Asyncio的工作原理
Asyncio和python主程序一样,只有一个主线程,但是可以进行多个不同任务(特殊的future对象,可类比为多线程里的多个线程),这些任务被一个event loop的对象所控制。
任务可分为两种状态:预备状态和等待状态
-
预备状态:任务目前空闲,但随时待命准备运行
-
等待状态:任务已经运行,但正在等待外部的操作完成,如I/O操作
event loop的执行过程:
- event loop会维护两个任务列表,分别对应预备和等待这两种状态
- 选取预备状态的一个任务(根据等待时间长短、占用资源等因素选取),使其运行直到该任务把控制权还给event loop为止
- 当接收到任务控制权后,event loop会根据其完成状态把任务放到对应的预备或等待状态的列表。遍历等待状态的列表,查看列表中的任务是否完成。已完成:放到预备状态的列表;未完成:继续放在等待状态的列表
- 原先在预备状态列表中的任务位置不变,因为它们仍未运行。当所有任务被重新放置在合适的列表后,新的一轮循环又开始了:event loop继续从预备状态的列表中选取一个任务使其执行…如此周而复始,直到所有任务都完成
对于asyncio来说,它的任务在运行时不会被外部的一些因素打断,因此asyncio内的操作不会出现race condition的情况,就不需要担心线程安全的问题了