6.1 獲取事件循環
事件循環 (Event Loop) 是 Python 中使用 asyncio 模塊進行 非同步編程的核心組件。它管理非同步任務的執行、事件的處理和 輸入輸出的操作。事件循環允許多個任務同時執行,而不會阻塞主 執行線程。
創建和獲取事件循環
-
asyncio.get_event_loop(): 返回當前的 事件循環,如果沒有則創建一個新的。 -
asyncio.new_event_loop(): 創建一個新的 事件循環。 -
asyncio.set_event_loop(loop): 設置指定的 事件循環為當前。
範例:
asyncio 有一個當前的事件循環,其中包含所有執行中的任務。 您可以獲取當前的事件循環或創建一個新的並將其設置為當前。 這正是下面的範例中發生的情況。
import asyncio
loop = asyncio.get_event_loop()
print(loop) # 當前事件循環
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
print(asyncio.get_event_loop()) # 新設置的事件循環
值得注意的是,方法 get_event_loop() 返回當前活躍的事件循環。 創建新事件循環並設置它應該謹慎使用,以避免在非同步應用中發生衝突。
運行事件循環
-
run_forever(): 啟動事件循環並持續執行,直到調用stop()。 -
run_until_complete(future): 啟動事件循環,並在指定的 coroutine 完成後終止。
範例:
事件循環可以以兩種模式運行:無限循環——類似於 while True,或直到完成指定任務。
import asyncio
async def hello():
print("Hello")
await asyncio.sleep(1)
print("World")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
如果你啟動了 Event Loop 在 run_forever() 模式,它會不斷地執行循環。 方法 run_forever() 只有當某個非同步任務調用我們的 EventLoop 的 方法 stop() 才會終止運行。
停止事件循環
stop(): 停止事件循環。-
is_running(): 如果事件循環運行中,返回True。
範例:
如果循環是以無限模式運行的,它會不斷接收任務並執行,自己不會停止。 必須有人獲取我們當前循環的對象並調用其方法 stop()。 要知道無限循環是否在運行,應調用方法 is_running()。
import asyncio
loop = asyncio.get_event_loop()
loop.stop()
print(loop.is_running()) # False
6.2 重要的事件循環方法
方法 call_soon(callback, *args)
計劃盡快調用函數 callback 與參數 *args。
import asyncio
def my_callback():
print("Callback executed")
loop = asyncio.get_event_loop()
loop.call_soon(my_callback)
loop.run_forever()
將函數 callback 放在任務列表的最前面,以便儘快開始執行。 方法可以傳遞非非同步函數。此方法在需要以最小延遲執行任務時特別有用, 尤其是在非同步應用中需要及時回應的情況下。
方法 call_later(delay, callback, *args)
計劃在 delay 秒後調用函數 callback 與參數 *args。
import asyncio
def my_callback():
print("Callback executed after delay")
loop = asyncio.get_event_loop()
loop.call_later(2, my_callback)
loop.run_forever()
此方法允許延遲調用函數:第一個參數是延遲時間(可以是小數), 然後是函數的引用和其參數。方法可以傳遞非非同步函數。 此方法可用於管理不同優先級的任務執行,對於設計複雜的非同步系統尤其有用。
方法 call_at(when, callback, *args)
計劃在時間點 when 調用函數 callback 與參數 *args。
import asyncio
import time
def my_callback():
print("Callback executed at specific time")
loop = asyncio.get_event_loop()
when = loop.time() + 2 # 事件循環當前時間加2秒
loop.call_at(when, my_callback)
loop.run_forever()
如果你想在具體時間點(比如下午3點或晚上12點)而不是5秒後執行任務, 你會發現 方法 call_at() 和 方法 call_soon() 非常相似,但第一個參數傳遞的是時間 而非延遲時長。方法可以傳遞非非同步函數。
優勢和特點
非同步執行: 事件循環允許多個任務平行執行,不阻塞主執行線程。
資源有效管理: 非同步 I/O 操作無需阻塞,這使得程序更高效。
靈活性和擴展性: 事件循環支持多種方法來規劃任務和處理事件, 這允許創建複雜且擴展性強的非同步應用。
6.3 與任務和未來對象的交互
事件循環管理任務 (Tasks) 和未來對象 (Futures) 的執行。 它跟踪它們的狀態並確保它們在準備好後執行。
範例:
import asyncio
async def main():
await asyncio.sleep(1)
print("Task completed")
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)
這個範例展示了如何用事件循環管理使用方法 create_task 創建的任務。 方法 call_soon(), call_later() 和 call_at() 可用於管理不同優先級的任務執行,這對於設計複雜的非同步系統尤其有用。
GO TO FULL VERSION