[英]Will functions run twice with asyncio.gather(create_task(task))
[英]asyncio create_task to run forever
我有以下代碼
import asyncio
loop = asyncio.get_event_loop()
async def while_loop():
n = 0
while True:
print(f"{n}")
await asyncio.sleep(2)
n = n+1
async def some_func():
await asyncio.sleep(5)
print("Some Func")
future = loop.create_task(while_loop())
loop.run_until_complete(some_func())
我希望while_loop
函數永遠運行,但它似乎只是作為調用run_until_complete
的結果而執行,並且一旦some_func
完成執行,它就會停止打印 while 循環。 我看到的輸出是:
0
1
2
Some Func
我希望即使在some_func
完成后這些數字也會繼續打印。
0
1
2
Some Func
3
4
5
6
.
.
.
打印更多數字的唯一方法是再次調用some_func
。
我希望即使在
some_func
完成后這些數字也會繼續打印。
run_until_complete
的參數控制事件循環運行的時間。 一旦事件循環停止運行,所有協程都會有效地暫停,而不僅僅是您一直在等待的協程。 但是您確實有不同的選擇:
loop.run_until_complete(some_func())
- 你已經使用過的; 運行事件循環,直到some_func
協程完成。 在此期間也並行執行其他協程,但也會在事件循環完成后立即停止執行它們。
loop.run_forever()
- 運行事件循環,直到某個協程或回調調用loop.stop()
。 如果他們都沒有這樣做,那么即使所有協程都結束了,事件循環也不會停止。 在你的情況下,你會調用loop.create_task(while_loop())
然后是loop.create_task(some_func())
,然后是loop.run_forever()
。
loop.run_until_complete(asyncio.gather(while_loop(), some_func()))
直到兩個指定的協程完成運行事件循環。 這(等待所有任務)顯然是您期望loop.run_until_complete()
自動執行的操作,即使您只指定一個,但它不會像那樣工作,它會在指定的協程完成后立即停止。 asyncio.gather
可用於一次等待多個協程。 有關等待的更微調控制,另請參閱asyncio.wait
。
由於您的協程之一永遠運行,最后兩個選項將是等效的,並會產生預期的輸出。
這是我用來async with
上下文保持async with
永遠活着的方法:
def never():
try:
return never.never
except AttributeError:
never.never = asyncio.Future()
return never.never
async def create_context_and_dependent_tasks():
async with create_ctx() as ctx:
for i in range(10):
asyncio.create_task(use_ctx_indefinitely(bar))
await never() # **THIS** is the main idea I wanted to talk about.
它不適用於多個循環,但這很少是一種情況(並且可以通過對never
函數進行輕微修改來解決):
def never():
loop = asyncio.get_running_loop()
try:
return never.nevers[loop]
except KeyError:
never.nevers[loop] = asyncio.Future()
return never.nevers[loop]
never.nevers = {}
問題是,如果您創建了本地未來:
async def foo():
never = asyncio.Future()
await never
它會被垃圾收集,任務會被銷毀……只是因為 Python 充滿了驚喜。 所以你必須在全局范圍內創建未來(但不是一開始,因為循環還不存在)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.