簡體   English   中英

檢查 asyncio.get_event_loop() 是否已完成?

[英]Check if asyncio.get_event_loop() has finished?

我有一個自定義背景裝飾器。 當我在后台運行一個函數時,如何檢查我在后台啟動的所有函數是否在我返回之前都已完成?

#background decorator
def background(fn):
    def wrapped(*args, **kwargs):
        return asyncio.get_event_loop().run_in_executor(None, fn, *args, **kwargs)
    return wrapped
#myfunction that I run in the background
@background
def myfunction():
    #run some tasks
#main here I call "myfunction"
def main():
    for i in list:
        myfunction()
#check if all myfunction's are done then return (MY PROBLEM)

您可以列出 myfunction() 任務,然后使用 asyncio.wait() 運行它們

import asyncio
from timeit import default_timer as timer

def background(fn):
    def wrapped(*args, **kwargs):
        return asyncio.get_event_loop().run_in_executor(None, fn, *args,**kwargs)
    return wrapped

@background
def myfunction(tasknum):
    print("tasknum",tasknum," -- started at", timer())
    #add lots of numbers to simulate some task...
    x = 0
    for n in range(20000000):
        x += n
    print("tasknum",tasknum," -- finished at", timer())

def main():
    print("main -- started at", timer())
    background_loop = asyncio.get_event_loop()
    tasks = []

    for i in range(4):
        tasks.append(myfunction(i))

    try:
        background_loop.run_until_complete(asyncio.wait(tasks))
    finally:
        background_loop.close()

    print("main -- finished at", timer())

main()
print('returned from main')

輸出:

main -- started at 38203.24129425
tasknum 0  -- started at 38203.241935683
tasknum 1  -- started at 38203.24716722
tasknum 2  -- started at 38203.257414232
tasknum 3  -- started at 38203.257518981
tasknum 1  -- finished at 38206.503383425
tasknum 2  -- finished at 38206.930789807
tasknum 0  -- finished at 38207.636296604
tasknum 3  -- finished at 38207.833483453
main -- finished at 38207.833736195
returned from main

注意get_event_loop()在python 3.10中是折舊的,所以最好的解決方案可能是在裝飾器定義之前啟動后台循環,然后直接使用循環名稱:

background_loop = asyncio.new_event_loop()

def background(fn):  
    def wrapped(*args, **kwargs):
        return background_loop.run_in_executor(None, fn, *args, **kwargs)
    return wrapped

在 main 函數之外,您應該定義循環,並使用它來等待將在 main 中運行的所有函數,直到它們完成:

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())  # <- This is what you are looking for
loop.close()

然后,在你的包裝函數中,像這樣使用這個循環:

await loop.run_in_executor(...)

並記住在適當的地方使用asyncawait表達式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM