这段示例代码无限期挂起:
import asyncio
async def main():
async def f():
await g_task
async def g():
await f_task
f_task = asyncio.create_task(f())
g_task = asyncio.create_task(g())
await f_task
asyncio.run(main())
我正在寻找一种自动检测和处理死锁的方法,就像GoLang所做的那样。
到目前为止,我想出了一种
asyncio.wait_for()
的变体:[编辑]设计进行了大修 https://gist.github.com/gimperiale/549cbad04c24d870145d3f38fbb8e6f0 在原始代码中进行了1行更改:
await wait_check_deadlock(f_task)
它可以运行,但存在两个主要问题:
- 它依赖于 CPython 的实现细节
asyncio.Task._fut_waiter
- 死锁的任务将永远保留在 RAM 中。
aw.cancel()
似乎没有作用。如果我捕获了辅助函数引发的 RecursionError,则 asyncio.run() 在尝试取消所有任务时会引发另一个 RecursionError。
是否有更健壮的解决方案?
asyncio
和async/await
是否支持取消,因为只要对f_task
或g_task
的引用在“外部”可用,即对于某些其他协程,该其他代码可以调用f_task.cancel()
。除了目前存在的问题:https://bugs.python.org/issue36456 - Dima Tisnek