簡體   English   中英

Python asyncio等待超時不適用於無限任務

[英]Python asyncio await-for timeout doesn't work for infinite task

在 Python 3.8 中,我想我明白為什么除非我包含asyncio.sleep(1)否則下面的forever函數也不會在 1 秒后超時。 這是因為它在離開隊列后開始執行並且隊列中沒有其他任務運行,因為它從不阻塞?

我需要完成的是調用用戶提供的一些函數(如永遠)。 他們可能會給我一個永遠不會返回的函數(例如它無限循環並且不會阻塞)。 那么如何獲得我想要的調用用戶函數並允許它運行直到超時的效果呢?

import asyncio

async def long_time():
    # Sleep for one hour
    await asyncio.sleep(3600) 
    print('yay!')

async def forever():
    while True:
        pass
        #await asyncio.sleep(1)

async def main():
    # Wait for at most 1 second
    try:
        await asyncio.wait_for(long_time(), timeout=1.0)
    except asyncio.TimeoutError:
        print('timeout 1!')
    try:
        await asyncio.wait_for(forever(), timeout=1.0)
    except asyncio.TimeoutError:
        print('timeout 2!')

asyncio.run(main())

Async/await 使用單個線程在異步任務(事件循環、隊列)之間切換。

您的任務不會超時,因為您以同步方式無限執行並且不允許任何其他異步任務(或同一線程中的任何其他代碼)接管,從而forever完全阻塞線程。 如果您預計用戶提供的某些函數可能包含非常長的同步計算,那么您應該使用單獨的進程來運行這樣的函數。

理論上,您可以使用單獨的線程而不是進程,但不能在 CPython 中使用,因為GIL 使用 GIL 一次只能有一個線程執行代碼。

暫無
暫無

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

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