Python?異步之如何獲取當(dāng)前和正在運(yùn)行任務(wù)詳解
正文
我們可以反省在 asyncio 事件循環(huán)中運(yùn)行的任務(wù)。這可以通過為當(dāng)前運(yùn)行的任務(wù)和所有正在運(yùn)行的任務(wù)獲取一個 asyncio.Task 對象來實(shí)現(xiàn)。
1. 如何獲取當(dāng)前任務(wù)
我們可以通過 asyncio.current_task() 函數(shù)獲取當(dāng)前任務(wù)。此函數(shù)將為當(dāng)前正在運(yùn)行的任務(wù)返回一個任務(wù)對象。
... # get the current task task = asyncio.current_task()
- 傳遞給 asyncio.run() 的主協(xié)程。
- 通過 asyncio.create_task() 在 asyncio 程序中創(chuàng)建和調(diào)度的任務(wù)。
一個任務(wù)可以創(chuàng)建并運(yùn)行另一個協(xié)程(例如,不包含在任務(wù)中)。從協(xié)程中獲取當(dāng)前任務(wù)將為正在運(yùn)行的任務(wù)返回一個 Task 對象,但不會返回當(dāng)前正在運(yùn)行的協(xié)程。
如果協(xié)程或任務(wù)需要有關(guān)自身的詳細(xì)信息,例如用于日志記錄的任務(wù)名稱,則獲取當(dāng)前任務(wù)會很有幫助。
我們可以探索如何為用于啟動 asyncio 程序的主協(xié)程獲取 Task 實(shí)例。下面的示例定義了一個用作程序入口點(diǎn)的協(xié)程。它報(bào)告一條消息,然后獲取當(dāng)前任務(wù)并報(bào)告其詳細(xì)信息。
這是第一個重要的示例,因?yàn)樗鼜?qiáng)調(diào)所有協(xié)程都可以作為異步事件循環(huán)中的任務(wù)進(jìn)行訪問。
下面列出了完整的示例。
# SuperFastPython.com # example of getting the current task from the main coroutine import asyncio # define a main coroutine async def main(): # report a message print('main coroutine started') # get the current task task = asyncio.current_task() # report its details print(task) # start the asyncio program asyncio.run(main())
運(yùn)行該示例首先創(chuàng)建主協(xié)程并使用它來啟動 asyncio 程序。main() 協(xié)程運(yùn)行并首先報(bào)告一條消息。
然后它檢索當(dāng)前任務(wù),這是一個代表自身的任務(wù)對象,即當(dāng)前正在運(yùn)行的協(xié)程。然后它會報(bào)告當(dāng)前正在運(yùn)行的任務(wù)的詳細(xì)信息。
我們可以看到該任務(wù)具有第一個任務(wù)的默認(rèn)名稱“Task-1”,并且正在執(zhí)行 main() 協(xié)程,即當(dāng)前正在運(yùn)行的協(xié)程。
這突出表明我們可以使用 asyncio.current_task() 函數(shù)來訪問當(dāng)前正在運(yùn)行的協(xié)程的任務(wù)對象,該對象自動包裝在任務(wù)對象中。
main coroutine started <Task pending name='Task-1' coro=<main() running at ...> cb=[_run_until_complete_cb() at ...]>
2. 如何獲取所有任務(wù)
我們可能需要訪問異步程序中的所有任務(wù)。這可能有很多原因,例如:
- 反省程序的當(dāng)前狀態(tài)或復(fù)雜性。
- 記錄所有正在運(yùn)行的任務(wù)的詳細(xì)信息。
- 查找可以查詢或取消的任務(wù)。
我們可以通過 asyncio.all_tasks() 函數(shù)在 asyncio 程序中獲取一組所有已計(jì)劃和正在運(yùn)行(尚未完成)的任務(wù)。
... # get all tasks tasks = asyncio.all_tasks()
這將返回 asyncio 程序中所有任務(wù)的集合。它是一個集合,因此每個任務(wù)只代表一次。
如果出現(xiàn)以下情況,將包括一項(xiàng)任務(wù):
- 任務(wù)已安排但尚未運(yùn)行。
- 該任務(wù)當(dāng)前正在運(yùn)行(例如,但當(dāng)前已暫停)
該集合還將包括當(dāng)前正在運(yùn)行的任務(wù)的任務(wù),例如正在執(zhí)行調(diào)用 asyncio.all_tasks() 函數(shù)的協(xié)程的任務(wù)。
另外,回想一下用于啟動 asyncio 程序的 asyncio.run() 方法會將提供的協(xié)程包裝在任務(wù)中。這意味著所有任務(wù)的集合將包括程序入口點(diǎn)的任務(wù)。
我們可以探索在一個 asyncio 程序中有很多任務(wù)的情況,然后得到一組所有任務(wù)。
在此示例中,我們首先創(chuàng)建 10 個任務(wù),每個任務(wù)包裝并運(yùn)行相同的協(xié)程。主協(xié)程然后獲取程序中計(jì)劃或運(yùn)行的所有任務(wù)的集合并報(bào)告它們的詳細(xì)信息。
下面列出了完整的示例。
# SuperFastPython.com # example of starting many tasks and getting access to all tasks import asyncio # coroutine for a task async def task_coroutine(value): # report a message print(f'task {value} is running') # block for a moment await asyncio.sleep(1) # define a main coroutine async def main(): # report a message print('main coroutine started') # start many tasks started_tasks = [asyncio.create_task(task_coroutine(i)) for i in range(10)] # allow some of the tasks time to start await asyncio.sleep(0.1) # get all tasks tasks = asyncio.all_tasks() # report all tasks for task in tasks: print(f'> {task.get_name()}, {task.get_coro()}') # wait for all tasks to complete for task in started_tasks: await task # start the asyncio program asyncio.run(main())
運(yùn)行該示例首先創(chuàng)建主協(xié)程并使用它來啟動 asyncio 程序。main() 協(xié)程運(yùn)行并首先報(bào)告一條消息。然后它創(chuàng)建并安排 10 個包裝自定義協(xié)程的任務(wù)。然后 main() 協(xié)程會阻塞片刻以允許任務(wù)開始運(yùn)行。任務(wù)開始運(yùn)行,每個任務(wù)報(bào)告一條消息,然后休眠。
main() 協(xié)程恢復(fù)并獲取程序中所有任務(wù)的列表。然后它報(bào)告每個的名稱和協(xié)程。最后,它枚舉已創(chuàng)建的任務(wù)列表并等待每個任務(wù)完成。
這突出表明我們可以獲得 asyncio 程序中所有任務(wù)的集合,其中包括創(chuàng)建的任務(wù)以及代表程序入口點(diǎn)的任務(wù)。
main coroutine started
task 0 is running
task 1 is running
task 2 is running
task 3 is running
task 4 is running
task 5 is running
task 6 is running
task 7 is running
task 8 is running
task 9 is running
> Task-9, <coroutine object task_coroutine at 0x10e186e30>
> Task-2, <coroutine object task_coroutine at 0x10e184e40>
> Task-11, <coroutine object task_coroutine at 0x10e186f10>
> Task-7, <coroutine object task_coroutine at 0x10e186d50>
> Task-4, <coroutine object task_coroutine at 0x10e185700>
> Task-10, <coroutine object task_coroutine at 0x10e186ea0>
> Task-8, <coroutine object task_coroutine at 0x10e186dc0>
> Task-5, <coroutine object task_coroutine at 0x10e186ab0>
> Task-1, <coroutine object main at 0x10e1847b0>
> Task-3, <coroutine object task_coroutine at 0x10e184f90>
> Task-6, <coroutine object task_coroutine at 0x10e186ce0>
接下來,我們將探討如何同時(shí)運(yùn)行多個協(xié)程。
以上就是Python 異步之如何獲取當(dāng)前和正在運(yùn)行任務(wù)詳解的詳細(xì)內(nèi)容,更多關(guān)于Python 異步獲取當(dāng)前運(yùn)行任務(wù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python復(fù)合賦值運(yùn)算符由淺入深實(shí)例探究
這篇文章主要為大家介紹了Python復(fù)合賦值運(yùn)算符由淺入深實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Python+Selenium實(shí)現(xiàn)自動填寫問卷
這篇文章主要介紹了如何利用Python Selenium實(shí)現(xiàn)自動填寫問卷功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-03-03用Python設(shè)計(jì)一個經(jīng)典小游戲
本篇文章主要介紹如何用Python設(shè)計(jì)一個經(jīng)典小游戲:猜大小。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-05-05Python獲取任意xml節(jié)點(diǎn)值的方法
這篇文章主要介紹了Python獲取任意xml節(jié)點(diǎn)值的方法,涉及Python操作XML節(jié)點(diǎn)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05Python+tkinter實(shí)現(xiàn)一個繪圖風(fēng)格控件
這篇文章主要為大家詳細(xì)介紹了Python如何利用tkinter實(shí)現(xiàn)一個簡單的繪圖風(fēng)格控件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2023-09-09Python基礎(chǔ)學(xué)習(xí)之條件控制語句小結(jié)
如果我需要設(shè)置一個死循環(huán),然后靠條件來終止,怎么辦?一個很簡單的問題,但是我卻沒有說,這一篇本應(yīng)該在分支控制語句里面的,現(xiàn)在只能拿出來水文再寫一篇了,需要的朋友可以參考下2021-05-05使用Jest?在?Visual?Studio?Code?中進(jìn)行單元測試的流程分析
Jest是一個流行的JavaScript測試框架,它提供了簡潔、靈活和強(qiáng)大的工具來編寫和運(yùn)行單元測試,今天通過本文給大家介紹使用Jest在Visual Studio Code中進(jìn)行單元測試的流程分析,感興趣的朋友跟隨小編一起看看吧2023-07-07