深刻Asyncio(五)Event Loop

Event Loop

loop除了處理協程間的切換與結束時的異常捕捉,還要監聽socket和文件描述符。先作個小測試:bash

>>> import asyncio
>>> loop = asyncio.get_event_loop()
>>> loop2 = asyncio.get_event_loop()
>>> loop is loop2
True    # 兩個loop實例是徹底相同的

這意味着在一個coroutine內部獲取loop,也能夠經過asyncio.get_event_loop()來獲得,並不須要將loop做爲參數傳遞給協程函數。對於框架設計者來講狀況又不一樣了,最好在函數設計中接受一個loop參數,以防止用戶使用loop策略來作一些額外的事情。框架

注意get_event_loop()方法僅在一樣的線程中生效,若是在一個新線程中,應該用new_event_loop()來獲取新的loop,並經過set_event_loop(loop)來將其設爲該線程下的loop。socket

若是在一個coroutine函數中建立tasks而不await它們,會發生什麼?事實上它們將獨立於這個coroutine函數內的執行上下文來運行,這個coroutine函數將會在它啓動的任務完成以前退出。async

async def f():
    loop = asyncio.get_event_loop()
    for i in range(5):
        loop.create_task(<coro>)

像上述狀況,有時會在代碼中看到loop變量,而後create_task()才能被調用,另外一種解決方案是使用asyncio.ensure_future()方法,這個方法不須要經過loop來調用。函數

async def f():
    for i in range(5):
        asyncio.ensure_future(<coro>)

或能夠經過輔助函數來作到。oop

def create_task(coro):
    return asyncio.get_event_loop().create_task(coro)

async def f():
    for i in range(5):
        create_task(<coro>)

loop.create_task()asyncio.ensure_future()對初學者來講是很微妙和困惑的,下一章討論其中的差別。測試

相關文章
相關標籤/搜索