您好,登錄后才能下訂單哦!
這篇文章主要講解了“Python異步之怎么保護任務免于取消”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Python異步之怎么保護任務免于取消”吧!
Asyncio 任務可以通過調用它們的 cancel() 方法來取消。我們可以通過將任務包裝在對 asyncio.shield() 的調用中來保護任務不被取消。
asyncio.shield() 函數在 Future 中包裝了一個可等待對象,它將吸收要取消的請求。
這意味著被屏蔽的未來可以傳遞給可能嘗試取消它的任務,并且取消請求看起來像是成功的,除了被屏蔽的任務或協程將繼續運行。
它可能在 asyncio 程序中很有用,其中某些任務可以取消,但其他任務(可能具有更高優先級)則不能。
它也可能在某些任務可以安全取消的程序中很有用,例如那些在設計時考慮了 asyncio 的任務,而其他任務則不能安全終止,因此必須避免取消。
現在我們知道了 asyncio.shield() 是什么,讓我們看看如何使用它。
asyncio.shield() 函數將保護另一個任務或協程不被取消。它以一個可等待對象作為參數并返回一個 asyncio.Future 對象。
然后可以直接等待 Future 對象或將其傳遞給另一個任務或協程。
... # shield a task from cancellation shielded = asyncio.shield(task) # await the shielded task await shielded
返回的 Future 可以通過調用 cancel() 方法取消。
如果內部任務正在運行,請求將被報告為成功。
... # cancel a shielded task was_canceld = shielded.cancel()
任何等待 Future 對象的協程都會引發 asyncio.CancelledError,這可能需要處理。
... try: # await the shielded task await asyncio.shield(task) except asyncio.CancelledError: # ...
重要的是,對 Future 對象的取消請求不會傳播到內部任務。這意味著取消請求被護盾吸收了。
... # create a task task = asyncio.create_task(coro()) # create a shield shield = asyncio.shield(task) # cancel the shield (does not cancel the task) shield.cancel()
如果協程被提供給 asyncio.shield() 函數,它將被包裝在 asyncio.Task() 中并立即調度。
這意味著不需要等待屏蔽來讓內部協程運行。
如果被屏蔽的任務被取消,取消請求將向上傳播到屏蔽,屏蔽也將被取消。
... # create a task task = asyncio.create_task(coro()) # create a shield shield = asyncio.shield(task) # cancel the task (also cancels the shield) task.cancel()
現在我們知道如何使用 asyncio.shield() 函數,讓我們看一些有效的例子。
我們可以探索如何使用 asyncio.shield() 來保護任務不被取消。
在這個例子中,我們定義了一個簡單的協程任務,它接受一個整數參數,休眠一秒鐘,然后返回參數。然后可以創建協程并將其安排為任務。
我們可以定義第二個協程,它接受一個任務,休眠幾分之一秒,然后取消提供的任務。
在主協程中,我們可以屏蔽第一個任務,然后將其傳遞給第二個任務,然后等待被屏蔽的任務。
期望是屏蔽將被取消并保持內部任務完好無損。取消將中斷主協程。我們可以在程序結束時檢查內部任務的狀態,我們希望它已經正常完成,而不管屏蔽上的取消請求如何。
# SuperFastPython.com # example of using asyncio shield to protect a task from cancellation import asyncio # define a simple asynchronous async def simple_task(number): # block for a moment await asyncio.sleep(1) # return the argument return number # cancel the given task after a moment async def cancel_task(task): # block for a moment await asyncio.sleep(0.2) # cancel the task was_cancelled = task.cancel() print(f'cancelled: {was_cancelled}') # define a simple coroutine async def main(): # create the coroutine coro = simple_task(1) # create a task task = asyncio.create_task(coro) # created the shielded task shielded = asyncio.shield(task) # create the task to cancel the previous task asyncio.create_task(cancel_task(shielded)) # handle cancellation try: # await the shielded task result = await shielded # report the result print(f'>got: {result}') except asyncio.CancelledError: print('shielded was cancelled') # wait a moment await asyncio.sleep(1) # report the details of the tasks print(f'shielded: {shielded}') print(f'task: {task}') # start asyncio.run(main())
運行示例首先創建 main() 協程并將其用作應用程序的入口點。創建任務協程,然后將其包裝并安排在任務中。然后該任務就不會被取消。
然后將屏蔽的任務傳遞給 cancel_task() 協程,該協程包裝在任務中并進行調度。主協程然后等待受保護的任務,該任務需要 CancelledError 異常。
任務運行片刻然后休眠。取消任務運行片刻,休眠,恢復然后取消屏蔽任務。取消請求報告它已成功。
這會在受保護的 Future 中引發 CancelledError 異常,但不會在內部任務中引發。
main() 協程恢復并響應 CancelledError 異常,報告一條消息。然后它會睡一會兒。任務恢復、完成并返回一個值。
最后,main() 協程恢復,并報告被屏蔽的未來和內部任務的狀態。我們可以看到屏蔽的未來被標記為已取消,而內部任務被標記為正常完成并提供返回值。
此示例突出顯示了如何使用防護罩來成功保護內部任務不被取消。
cancelled: True shielded was cancelled shielded: <Future cancelled> task: <Task finished name='Task-2' coro=<simple_task() done, defined at ...> result=1>
感謝各位的閱讀,以上就是“Python異步之怎么保護任務免于取消”的內容了,經過本文的學習后,相信大家對Python異步之怎么保護任務免于取消這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。