5.1 Event Loop
現在簡單談談非同步的第二部分,總是從各方面冒出來的:事件循環 (Event Loop)
、任務 (Task)
和 Future
。
想像一下Event Loop是樂團的指揮,Task是音樂家,而Future是音樂家要演奏的樂譜。指揮 (Event Loop) 協調音樂家 (Task) 的工作,他們通過閱讀樂譜 (Future) 來演奏音樂 (非同步操作)。
事件循環 (Event Loop)
是Python中非同步程式設計的基礎。它負責執行非同步任務、管理事件和處理I/O。事件循環不斷檢查是否有新事件或任務,並在準備好時啟動它們。
主要功能
-
run_forever()
: 啟動事件循環並持續執行直到調用stop()
。 -
run_until_complete(future)
: 啟動事件循環,並在指定的future對象或協程完成後結束。 stop()
: 停止事件循環。-
create_task(coroutine)
: 計劃執行協程作為任務。
使用示例:
import asyncio
async def hello():
print("Hello, world!")
await asyncio.sleep(1)
print("Hello again!")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
在這個示例中,我們首先使用 get_event_loop()
方法來獲取當前 EventLoop
對象。
然後我們將協程 hello
添加到此 EventLoop
並請求它通過 run_until_complete()
方法執行。
在最後一步中,我們用 close()
方法關閉 EventLoop
。
執行此代碼時,您將看到首先輸出 "Hello, world!",然後程序將等待1秒,之後將輸出 "Hello again!"。這演示了Event Loop如何管理非同步函數的執行。
我們將在下一堂課中更詳細地討論這些操作。
5.2 Tasks
任務 (Tasks)
是對協程的包裝,允許管理其執行並跟踪其狀態。任務允許通過事件循環並行運行協程。
創建和管理任務
-
asyncio.create_task(coroutine)
: 創建一個執行協程的任務。 -
Task.result()
: 返回已完成任務的結果,或者如果任務以錯誤結束則引發異常。 Task.cancel()
: 取消任務的執行。
使用示例:
import asyncio
async def say_hello():
await asyncio.sleep(1)
print("Hello")
async def main():
task = asyncio.create_task(say_hello())
await task
asyncio.run(main())
在這個示例中,我們將協程 say_hello()
包裝為 Task
對象。它也是一個非同步對象,所以要獲得結果,需要對其應用 await
操作符。
執行此代碼時,程序將等待1秒,然後輸出 "Hello"。這顯示了Task如何管理協程的執行,以及我們可以如何使用await等待其完成。
下一堂課將更詳細地講解 Task
的使用。
5.3 Futures
物件 Future
代表非同步操作的結果,將在未來可用。它們允許通過設定結果或異常來管理非同步操作的狀態。
主要方法:
-
set_result(result)
: 設定Future
的結果。 -
set_exception(exception)
: 設定Future
的異常。 -
result()
: 返回Future
的結果,或者如果操作以錯誤結束則引發異常。 -
exception()
: 返回異常,如果有設置的話。
使用示例:
import asyncio
async def set_future(fut, value):
await asyncio.sleep(1)
fut.set_result(value)
async def main():
loop = asyncio.get_running_loop()
fut = loop.create_future()
await set_future(fut, 'Hello, future!')
print(fut.result())
asyncio.run(main())
在這個示例中,我們創建了一個Future,然後在一秒後設置其值,然後輸出結果。您將看到程序等待一秒,然後才輸出 'Hello, future!'。這演示了Future如何代表將在未來可用的結果。
與 Task
對象不同的是,Future
對象綁定到具體的 Event Loop
,執行中的非同步函數可以向它寫入結果。雖然通常情況下,這個過程略有不同。
Future
對象最常與 Task
任務一起使用,提供更高級別的非同步操作管理。
現在在您了解了 Event Loop
, Task
和 Future
之後,我們將對它們進行更深入的研究。
GO TO FULL VERSION