converse✪
#coding:utf-8
import asyncio
import time
async def corou1():
print("corou 1, {}".format(time.perf_counter()))
await asyncio.sleep(2)
print("corou 1, {}".format(time.perf_counter()))
async def corou2():
print("corou 2, {}".format(time.perf_counter()))
# await asyncio.sleep(2)
time.sleep(5)
print("corou 2, {}".format(time.perf_counter()))
async def corou3():
print("corou 3, {}".format(time.perf_counter()))
await asyncio.sleep(2)
print("corou 3, {}".format(time.perf_counter()))
async def main():
tasks = [asyncio.create_task(corou())for corou in [corou1,corou2,corou3] ]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
###########执行结果############
func 1, 0.3864962
func 2, 0.3866095
func 2, 5.386688
func 3, 5.387335
func 1, 5.3877248
func 3, 7.3883411
通过上述例子可以看出,协程corou1,corou2,corou3的执行顺序按照加入循环事件的顺序。协程corou1 通过 await asyncio.sleep(2) 让出控制权,协程corou2由于没有await让出控制权所以一直在执行。当corou2结束后,很显然corou1也已经执行完,但还是先执行协程corou3,等协程corou3通过await让出控制权后,协程corou1才执行。
从上可以看出:
- 协程是按照事件循环顺序执行。即使交出控制权的协程执行完毕任务后等待再次获取控制权完成剩余任务,也必须等到循环到该协程才能获得CPU控制权。不会由于该协程已经完成await的任务而直接给它。这就是解释,协程corou2执行完会继续执行协程corou3,而并非继续执行协程corou1。
- await是交出协程控制权的地方
- 从上述代码可以看出,协程中当执行耗时IO操作时,应及时释放控制权,否则其他协程即便完成任务也由于没有CPU控制权而无法继续执行任务。