近来学习了基于协程的异步编程, 做个知识点总结一下.
什么是协程?
协程不是计算机提供, 是程序员人为创造的. 协程也可以称为微线程, 是一种用户态内的上下文切换技术, 简而言之, 其实就是通过一个线程实现代码块相互切换执行.
常用的实现协程的方式
官方推荐我们使用 async 和 await 关键字 , 但是必须是 python3.5之后的版本.
协程的意义以及同步,异步
在一个线程中, 如果遇到IO 等待, 线程不会傻等, 利用空闲的时间去做其他事情.
普通方法: 先把三个 url 装在一个 list 里, 用 for 循环, 一个 url , 一个url 去下载.
使用协程: 在下载等待第一个 url 返回数据的时候,就 发送第二个请求去下载第二部电影, 依次类推, 可以提升效率.
因此, 我们上面的普通方法也叫同步方式, 使用协程的方式, 也就是异步方式(基于协程的异步方式, 实现异步的方式还有线程池, 进程池)
基于协程的异步编程的基本实现
事件循环: 可以理解成一个死循环, 检测到有需要执行的代码就会去执行.
协程函数: 定义一个函数的时候, 在函数名前面加上一个 async , 即 async def func() 这样的函数, 就是协程函数.
协程对象: 执行协程函数, 就会返回一个协程对象.
注意: 协程函数() 的时候, 并不会执行函数内部的代码, 只会生成一个协程对象, 如果要执行协程函数里的内容, 就需要将协程对象交给事件循环来处理.
1 | async def func(): |
在 python3.7之后, 就可以直接 asyncio.run(协程对象/task对象) ,就不需要还实例化 loop, 然后用 loop 来执行协程对象/task 对象了.
await 的使用
await + 可等待对象(协程对象, Future, Task对象-> 都属于IO 等待对象 )
注意: await 就是等待对象的值得到结果之后再继续向下走, 如果有多个 await 就要注意了. 一般一个 await 是等待一个 task的.
Task对象
简单白话:就是在事件循环中添加多个任务的. 所以我们可以在创建一个 task 对象的时候, 给它存放多个协程对象.
1 | import asyncio |
asyncio异步迭代器
其实就是和一般意义上的迭代器差不多, 只是用于异步中而已.其实异步迭代器, 也就是在 iter和next 方法前面都加了一个 a , aiter和 anext 方法, 同时拥有这两个方法的就是异步迭代器. aiter返回self, anext 返回的是一个 awaitable 对象.
其中有个注意事项, async for 必须写在协程函数内部, 否则语法就会报错. 我们通过这个有 async for 的协程对象来调用迭代器.
1 | import asyncio |
异步上下文管理器
和一般的上下文管理器类似, 都是先 执行什么, 最后再执行什么.只是异步上下文管理器用于异步编程.
1 | import asyncio |