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,不过维护这个方式的心智负担太大。

以上,可以用 asgirefasync_to_sync, sync_to_async 简化代码。

小建议,写代码的时候 PYTHONASYNCIODEBUG 开关打开,他会检测堵塞的 coroutine,或者没写 await 的 coroutine,这些东西要是忘记写了真是要命。