为什么要讲?
异步非阻塞、asyncio
tornado ,fastapi,django 3.x asgi、aiohttp都在异步> 提升性能
协程不是计算机提供,是程序员人为创造的。
协程(Coroutine),也可以被称为微线程,是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行。例如:
def funcl():print(1)...print(2)def func2():print(3)...print(4)fanc1func2
实现协程
有这么几种方法
- greenlet,早期模块
- yield关键字
- asyncio装饰器(py3.4)
- async、await关键字(py35)
greenlet实现协程

yield关键字 (了解)

如果一个函数里存在yield,被认为是一个生成器函数
asyncio 官方内置
python3.4及之后的版本。
写了一个装饰器
协程函数必须通过特殊写法执行。
注意:遇到IO阻塞会自动切换,(例如网络IO请求:下载一张图片 )
async、await关键字 (推荐)
其他并行
executor = concurrent.futures.ThreadPoolExecutor()
…
executor.submit(func)
executor.shutdown()
多进程 concurrent 线程/进程异步
executor = concurrent.futures.ProcessPoolExecutor
https://www.yuque.com/docs/share/bb76f22f-47a2-4315-b0e0-4afa31df8d2a?# 《w220321: 并行脚本加速》
协程意义
在一个线程中如果遇到IO等待时间,线程不会傻傻等,利用空闲的时候再去干点其他事。
asyncio异步编程
事件循环
理解成为一个死循环,去检测并执行某些代码:
import asyncio# 生成或获取一个事件循环loop=asyncio.get_event_loop()# 将任务放到“任务列表”loop.run_until_complete(asyncio.wait(tasks))|
快速上手
协程函数,定义函数时,async def 函数名;
协程对象,执行 协程函数() 得到的协程对象。
async def func():passresult = func()
注意:执行协程函数创建协程对象,函数内部代码不会执行。
import asyncioasync def func():print("快来吧")result = func()# loop = asyncio.get_event_loop()# loop.run_until_complete(result)asyncio.run(result) # python3.7
await关键字
await + 可等待的对象 (协程对象、Future、Task对象 -》IO等待(先理解))
示例一:
import asyncioasync def func():print("来玩呀")response = await asyncio.sleep(2)print("over", response)asyncio.run(func())
示例二:
示例三:
一个协程函数可以有多个await
await就是等待对象的值得到结果之后在继续向下走。
Task对象

白话:在事件循环中添加多个任务的。
示例一:
示例二:
await返回一个元组,2个值,
done是一个集合,
pending,
async.run 等价于 时间循环创建+加列表
示例三:
错误:task里会立即加入事件循环,所以错
改进:
Future对象
底层、不常用。
task的基类。
_state
Task基础Future,Task对象内部await结果的处理基于Future对象来的。
示例一:
会一直等,除非赋值了
示例二:
concurrent.future.Future对象
使用线程池、进程池实现异步操作时用到的对象。
交叉使用
以后写代码可能会存在交叉时间。例如:crm项目80%都是基于协程异步编程+MySQL(不支持)【线程、进程做异步编程】
通过使用线程池或进程池使第三方模块能够异步编程,进而可以和协程异步编程一起完成项目。
案例:asyncio + 不支持异步的模块

asyncio异步迭代器


async for得写在协程函数内。
asyncio 异步上下文管理

支持async with ,也得写在协程函数里。 打开、关闭
uvloop 内部用了 这个快
是asyncio的事件循环的替代方案。事件循环效率 > 默认的asyncio的事件循环。
pip install uvloop
在进行asyncio编程时,加入2行代码:
import uvloopasyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

实战案例
异步redis
在通过python代码操作redis时,链接/操作/断开都是网络IO。
