8.16. 總結¶
你已走過 asyncio 的 API——在單一 CPU 上並行執行多項工作所需的各個部分:
協作式排程 ——本模組其餘部分所立基的模型。正在執行的協程獨佔事件迴圈,直到它
await;切換只會發生在那些 await 處。協程與任務 ——
async def定義一個工作單元;asyncio.create_task()並行排程一個工作單元,並回傳一個Task,應用程式稍後可對其等待、取消或辨識。事件迴圈 ——執行協程與任務的引擎。
asyncio.run()是大多數指令碼唯一需要的進入點;Loop類別為極少數需要的情況揭露了其餘功能。協調 ——
gather()用於扇出與扇入,wait_for()用於設定期限,Task.cancel與finally子句的清理模式,例外透過任務與 gather 呼叫傳播,以及事件迴圈的例外處理常式掛勾。同步原語 ——
Event用於協程之間的訊號傳遞,Lock用於跨越多個 await 將對共享資源的存取序列化,以及ThreadSafeFlag用於從中斷處理常式喚醒 asyncio 任務。自訂非同步物件 ——讓應用程式類別得以接入 asyncio 慣用法的語言掛勾。
__await__用於本身即為await對象的物件,__aiter__/__anext__用於async for,__aenter__/__aexit__用於async with。影格擷取 ——將
csi.CSI.snapshot()轉換為對await友善的協程的包裝器,使擷取迴圈得以與其他 asyncio 工作並行執行。陷阱 ——遺漏的
await、沒有讓步的緊密迴圈、被吞掉的取消、跨越多個 await 被變動的共享狀態,以及其餘 asyncio 特有的陷阱。
這已足以撰寫在同一個事件迴圈上混合相機工作、硬體 I/O 與並行背景工作的程式。
8.16.1. 日後使用本參考¶
請將 asyncio 各章視為參考資料;為了查閱 async with 的形式,或 gather() 在某個兄弟任務失敗時的確切行為而回頭翻閱,正是其預期用途。asyncio 參考頁面在一個地方列出了每個函式與類別,適合用於「這個呼叫的確切名稱是什麼」這類問題。
若需要建立在本模組之上的更豐富原語——號誌、佇列、屏障,以及一大批應用導向的輔助工具——peterhinch/micropython-async 程式庫是社群維護的標準來源。
8.16.2. 接下來該往哪走¶
網路 是下一個主要主題。asyncio.open_connection()、asyncio.start_server() 與 Stream 類別,正是 asyncio 指令碼從協程內部與網路其餘部分溝通的方式,並搭配其底層的 network 與 socket 模組。你所學到關於 await、Task、取消與同步原語的一切,都可直接沿用。