非同步任務是一個調度並獨立運行 asyncio 協程的物件。它提供了一個調度協程的句柄,asyncio 程式可以查詢並使用它來與協程互動。
任務是從協程建立的。它需要一個協程對象,包裝協程,安排它執行,並提供與之互動的方法。任務獨立執行。這意味著它被安排在 asyncio 事件循環中,並且無論創建它的協程中發生了什麼,它都會執行。這與直接執行協程不同,後者呼叫者必須等待它完成。
asyncio.Task 類別擴展了 asyncio.Future 類,一個實例是可等待的。 Future 是一個較低級別的類,代表最終會到達的結果。擴展 Future 類別的類別通常被稱為 Future-like。
因為非同步任務是可等待的,這表示協程可以使用 await 表達式等待任務完成。
... # wait for a task to be done await task
現在我們知道什麼是 asyncio 任務,讓我們看看如何建立一個。
使用提供的協程實例建立任務。回想一下協程是使用 async def 表達式定義的,看起來像一個函數。
# define a coroutine async def task_coroutine(): # ...
任務只能在協程中建立和調度。建立和排程任務有兩種主要方式,它們是:
使用進階API 建立任務(首選)
使用低階API 建立任務
可以使用asyncio.create_task() 函數建立任務。 asyncio.create_task() 函式接受一個協程實例和一個可選的任務名稱,並傳回一個 asyncio.Task 實例。
... # create a coroutine coro = task_coroutine() # create a task from a coroutine task = asyncio.create_task(coro)
這可以透過在一行中使用複合語句來實現。
... # create a task from a coroutine task = asyncio.create_task(task_coroutine())
這將做幾件事:
將協程包裝在非同步任務實例中。
安排任務在目前事件循環中執行。
傳回一個任務實例
任務實例可以被丟棄,透過方法與之交互,並由協程等待。這是從 asyncio 程式中的協程建立任務的首選方法。
也可以使用較低階的 asyncio API 從協程建立任務。
第一種方法是使用 asyncio.ensure_future() 函式。此函數採用任務、未來或類似未來的對象,例如協程,以及可選的用於調度它的循環。如果沒有提供循環,它將被安排在當前事件循環中。
如果為這個函數提供了協程,它會為我們包裝在一個實例中,然後返回。
... # create and schedule the task task = asyncio.ensure_future(task_coroutine())
我們可以用來建立和調度任務的另一個低階函數是 loop.create_task() 方法。此函數需要存取特定的事件循環,在該事件循環中將協程作為任務執行。
我們可以透過 asyncio.get_event_loop() 函式來取得 asyncio 程式中目前事件循環的實例。然後可以使用它來呼叫 create_task() 方法來建立一個 Task 實例並安排它執行。
... # get the current event loop loop = asyncio.get_event_loop() # create and schedule the task task = loop.create_task(task_coroutine())
創建任務後的一個常見問題是它什麼時候運行?
雖然我們可以透過 create_task() 函數調度協程作為任務獨立運行,但它可能不會立即運行。事實上,直到事件循環有機會運行,任務才會執行。
直到所有其他協程都沒有運行並且輪到任務運行時才會發生這種情況。
例如,如果我們有一個 asyncio 程序,其中有一個建立和調度任務的協程,則調度的任務將不會運行,直到創建任務的呼叫協程被掛起。
如果呼叫協程選擇休眠,選擇等待另一個協程或任務,或選擇等待已排程的新任務,則可能會發生這種情況。
... # create a task from a coroutine task = asyncio.create_task(task_coroutine()) # await the task, allowing it to run await task
現在我們知道什麼是任務以及如何安排它們。
以上是Python中怎麼創建和運行非同步任務的詳細內容。更多資訊請關注PHP中文網其他相關文章!