在概述中我们大致了解了一下异步的基本原理,接下来,我们会通过学习python的asyncio模块,来深入了解python异步的原理和使用。并且,在这个过程中,我们还会利用一个底层库,比如select等,来模拟一下事件回调的实现。
协程和python异步语法糖
协程,又叫微线程,其实就是在事件循环中运行的任务,其实也是一个python函数。python线程内,可以在不同的协程间切换。协程可以保存状态暂停执行,也可以恢复执行。
async和await
在python3.6之后,引入了两个异步关键字语法糖,定义和执行协程,即async和await
import asyncio
async def coro1():
print("Hello World")
async def coro2():
await coro1()
asyncio.run(coro2())
上述代码使用async def定义了两个协程函数。需要注意的是,协程函数与python的普通函数是不同的,普通的python函数,使用函数名加括号,就可以执行函数,而协程函数,使用函数名加括号,只是生成了一个协程对象,函数本身并不会执行。
要执行协程,要么在协程前面加await关键字(await必须在async定义的协程函数内部才能使用),一种就是使用asyncio.run()方法。
我们在概述中提到,python的异步是在一个事件循环中,不断地检查任务队列的任务状态,并执行某个任务。这里并没有体现出事件循环来。
其实是有的。上面的代码还有另一种写法:
import asyncio
async def coro1():
print("Hello World")
async def coro2():
await coro1()
loop = asyncio.get_event_loop()
loop.run_until_complete(coro2())
asyncio.get_event_loop(),就是获取到当前的事件循环,这个事件循环一般是自动生成的(除非用别的事件循环替代,后面会说到uvloop)。loop.run_until_complete(coro2())就是在事件循环中运行coro2。
只不过asyncio.run()自动帮我们做了上面两步。
async是定义协程对象,而await就是执行协程对象。
await的意思是,等待,等待后面的协程对象执行完成,并返回结果。
所以,当遇到await的时候,主协程就会暂停,去运行await后面的协程对象,等到协程执行完成并且返回后,主协程继续执行。所以,协程遇到await就会切换,这里的切换是指,从当前协程切换到调用的协程,直到这里,其实跟普通函数调用是一样的,我在一个函数里调用另一个函数,也是要等到调用函数执行完成后,主函数才会继续执行。那这里的意义是什么呢?如果是协程嵌套,或者一个个await,那与普通函数调用确实没有区别,所以,我们不能单纯地使用await执行协程,就以为它会自动切换。下面举个例子:
import asyncio
import time
async def coro1():
print('coro1 running')
await asyncio.sleep(2)
print('coro1 ended')
async def coro2():
print('coro2 running')
await asyncio.sleep(2)
print('coro1 ended')
async def coro3():
print('coro3 running')

最低0.47元/天 解锁文章
1427

被折叠的 条评论
为什么被折叠?



