python 異步編程:多個庫共用一個事件循環(huán)
在 Python 異步編程中,特別是當(dāng)同時使用多個異步庫(例如 fastapi 和 aiohttp)時,理解事件循環(huán)至關(guān)重要。 一個常見的疑問是:這些庫是否各自擁有獨立的事件循環(huán),還是共享一個?
答案是:只有一個全局的 asyncio 事件循環(huán)。
Python 的異步編程框架通常構(gòu)建于 asyncio 庫之上。asyncio 提供了事件循環(huán)的管理機制,允許程序在一個循環(huán)中高效地處理多個異步任務(wù)。 當(dāng)您使用 FastAPI 或 aiohttp 等庫時,它們并非創(chuàng)建自己的事件循環(huán),而是利用并整合到 asyncio 提供的全局事件循環(huán)中。
例如,一個 FastAPI 應(yīng)用啟動時會隱式地或顯式地創(chuàng)建一個 asyncio 事件循環(huán)。當(dāng) FastAPI 的異步視圖函數(shù)內(nèi)部調(diào)用 aiohttp 發(fā)起 HTTP 請求時,aiohttp 會直接使用這個已經(jīng)存在的事件循環(huán),而不會創(chuàng)建新的循環(huán)。 這避免了事件循環(huán)之間的沖突和資源浪費,簡化了異步程序的管理。
立即學(xué)習(xí)“Python免費學(xué)習(xí)筆記(深入)”;
以下代碼示例說明了這一點:
from fastapi import FastAPI import aiohttp app = FastAPI() @app.get("/") async def root(): async with aiohttp.ClientSession() as session: async with session.get("https://example.com") as resp: return await resp.text() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
在這個例子中,uvicorn 啟動 FastAPI 應(yīng)用時會初始化一個 asyncio 事件循環(huán)。root 函數(shù)中的 aiohttp 請求則在這個已存在的循環(huán)中執(zhí)行。
因此,即使使用了多個異步庫,它們也協(xié)調(diào)地運行在同一個事件循環(huán)中,保證了異步程序的效率和一致性。 這種單一事件循環(huán)的設(shè)計是 Python 異步編程的核心優(yōu)勢之一。