Python Async 简明教程
本文给 Python async 框架做了一个 higher-level overview。
首先要理解的两个世界:同步的世界和异步的世界。他们截然不同,库不同,调用方式也不同,虽然可能会共用一些东西。同步的代码只能同步调用,异步的代码只能异步调度。如果非要在同步的代码里调用异步的,或者反之,那么就需要显式地添加胶水代码。
异步的代码在 event loop 中调用,代码被封装称 coroutines 来运行,coroutines 里面会一直同步运行直到运行到 await,然后暂停,被切出,event loop 会运行别的 coroutines。<= 这套技术叫做 cooperative multitasking。其最大的麻烦点主要在于代码运行失败会是 silent failure。
一般我们这么区分代码:async def 的是异步,除此之外的是同步;__init__
一定要同步。
函数调用分四种:
- 同步调同步:没啥好说
- 异步调异步:
await coro()
- 异步调同步:
loop.run_in_executor(executor, sync_f, *args)
- 同步调异步:
loop.run_until_complete(coro(*args))
如果要变态地 inside sync code running inside async code,那么要跳出 thread,使用 main event loop 运行东西。<= 最麻烦的其实就是这个。
由于 event loop 是 global per-thread,所以有个 trick 是每个 thread 搞自己的 event loop,不过维护这个方式的心智负担太大。
以上,可以用 asgiref
的 async_to_sync
, sync_to_async
简化代码。
小建议,写代码的时候 PYTHONASYNCIODEBUG
开关打开,他会检测堵塞的 coroutine,或者没写 await 的 coroutine,这些东西要是忘记写了真是要命。