【发布时间】:2020-10-26 21:19:16
【问题描述】:
假设我有这样的网络服务器:
from fastapi import FastAPI
import uvicorn
import asyncio
app = FastAPI()
def blocking_function():
import time
time.sleep(5)
return 42
@app.get("/")
async def root():
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(None, blocking_function)
return result
@app.get("/ok")
async def ok():
return {"ok": 1}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", workers=1)
据我了解,代码将在默认的 ThreadExecutorPool 中生成另一个线程,然后在线程池中执行阻塞函数。另一方面,考虑 GIL 的工作原理,CPython 解释器将只执行一个线程 100 ticks,然后它会切换到另一个线程以公平并给其他线程一个前进的机会。在这种情况下,如果 Python 解释器决定切换到正在执行 blocking_function 的线程怎么办?它会阻止who解释器等待time.sleep(5)上剩余的任何内容吗?
我问这个问题的原因是我观察到有时我的应用程序会阻塞blocking_function,但是我不完全确定这里发生了什么,因为我的blocking_function 非常特别——它与 COM 对话API 对象通过 win32com 库。我试图排除这是我陷入的一些 GIL 陷阱。
【问题讨论】:
标签: python multithreading asynchronous python-asyncio fastapi