ASGI 和 WSGI 下的同步、异步代码,分别在哪里执行?这篇在视图里直接打印线程名和事件循环状态,请求真实的 uvicorn / gunicorn 进程,把四种组合的执行位置量出来。
ASGI (uvicorn) async def → 线程 MainThread 是主线程: True 该线程里有运行中的事件循环: True ASGI (uvicorn) def → 线程 ThreadPoolExecutor-5_0 是主线程: False 该线程里有运行中的事件循环: False WSGI (gunicorn) async def → 线程 ThreadPoolExecutor-2_0 是主线程: False 该线程里有运行中的事件循环: True WSGI (gunicorn) def → 线程 MainThread 是主线程: True 该线程里有运行中的事件循环: False
结论只对「执行位置」:ASGI 下 async 视图直接在服务器的事件循环上跑;sync 视图被放到线程里。WSGI 下 sync 视图就是普通的同步调用;async 视图被包了一层,在临时的事件循环里跑完这一个请求(async_to_sync)。
6 次请求 sync 视图的线程名: ['ThreadPoolExecutor-2_0', 'ThreadPoolExecutor-3_0', 'ThreadPoolExecutor-4_0', 'ThreadPoolExecutor-5_0', 'ThreadPoolExecutor-6_0', 'ThreadPoolExecutor-7_0'] 不同的线程数: 6
线程名里的数字每次都不同,说明每个请求用的是新的线程(而不是共享的一个)。这与下一篇里 sync_to_async 的 thread_sensitive 行为是同一个机制。