8. Asyncio

到目前為止,教學中的每個指令碼都是循序的 -- 一次執行一行,而必須等待的呼叫(感測器讀取、網路往返、快照)會阻塞指令碼,直到它完成為止。當只有一件事要做時,這沒問題。然而一旦應用程式需要同時做好幾件事 -- 執行快照迴圈回應序列埠命令、同時透過網路上傳影格 -- 循序指令碼就會崩潰。第一個緩慢的呼叫會讓其他所有事情都無法繼續進展。

asyncio 模組是 MicroPython 的解答。它讓應用程式得以將數個工作描述為各自獨立的協程(coroutine),並在單一執行緒上協作式地並行執行它們 -- 目前正在執行的協程,每當必須等待時就將控制權交還給排程器。快照迴圈、UART 讀取器與網路客戶端都可以共存於同一個指令碼中,而其中一者緩慢的部分不再會凍結其他部分。

接下來的章節將涵蓋 async/await 關鍵字與 Task 生命週期、透過 gather()wait_for() 進行協調、取消與例外傳播、三種內建同步原語(EventLockThreadSafeFlag)、將應用程式類別接入 asyncio 慣用語法的語言掛勾、一個讓 snapshot() 能以協程形式執行的小型 CSI 包裝器,以及協作式排程所帶來的常見陷阱。

迴圈控制

影格擷取

陷阱

總結