python 中的协程其实就是一种高效的任务切换模式: 遇到需要等待的(例如io等待), 直接跳到其他任务去执行,不会傻傻的等到io结束才向下执行
先看一个如果没有异步的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import asyncio import time def func1(): print("this is func1 ") time.sleep(2) print("this is end of func1") def func2(): print("this is func2 ") time.sleep(2) print("this is end of func2") if __name__ == '__main__': func1() func2() |
运行结果:
1 2 3 4 5 |
this is func1 this is end of func1 this is func2 this is end of func2 python asyntest.py 0.06s user 0.02s system 1% cpu 4.105 total |
也就是说,我们如果没有异步,那么我们的程序运行时间至少是4秒,因为它傻傻的等到第一个2s结束以后又执行的第二个
但是,其实,当第一个程序在等待的时候,它完全可以干其他的,例如,跳到第二个程序func2开始执行,然后等到func1通知我们说sleep 够了,抓紧回来继续执行的时候再跳回来
看看异步的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import asyncio import time async def func1(): print("this is func1 ") await asyncio.sleep(2) print("this is end of func1") async def func2(): print("this is func2 ") await asyncio.sleep(2) print("this is end of func2") if __name__ == '__main__': tasks = [ func1(), func2() ] loop = asyncio.get_event_loop() loop.run_until_complete( asyncio.wait(tasks) ) |
看看运行结果:
1 2 3 4 5 |
this is func2 this is func1 this is end of func2 this is end of func1 python asyntest.py 0.06s user 0.02s system 4% cpu 2.094 total |
从时间来看很明显,同样是执行两个函数,但是异步的一共才花了了不到3s,最起码时间上有节省
我们详细说一下我们的异步程序:
其中最重要的是定义函数的时候我们前边加了 async 关键词, 让这个函数变成一个特殊的函数
然后函数中使用了await, await 的意思可以理解为,当程序运行到这个地方的时候,可能会有等待,无论是IO等待还是其他的,如果有其他的工作,可以先去忙其他的
那如何知道有没有其他工作呢?
其实就是这个loop = asyncio.get_event_loop()
这个就是创建了一个任务池子,池子里放任务,池子里的任务是可以相互切换的,例如我们的例子中,loop里放了俩task, 一个是func1 ,一个是func2
也就是,他俩其中任何一个遇到等待(await),就去查一下池子里有没有其他的任务,如果有,就去执行其他的,过会不再等待了,再回来执行
也就是我们的输出结果中并不是顺序执行结果的原因
Latest posts by Zhiming Zhang (see all)
- aws eks node 自动化扩展工具 Karpenter - 8月 10, 2022
- ReplicationController and ReplicaSet in Kubernetes - 12月 20, 2021
- public key fingerprint - 5月 27, 2021