有没有办法获取使用 asyncio.gather 调用的异步函数的回溯并查看哪个函数调用了它?

问题描述 投票:0回答:1

这个问题可以用这个例子来概括:

import asyncio
import traceback

async def func_c():
    print("func c")
    traceback.print_stack()

async def func_b():
    print("func b")
    tasks = [func_c() for _ in range(3)]
    await asyncio.gather(*tasks)
    
async def func_b_v2():
    print("func b v2")
    tasks = [func_c() for _ in range(3)]
    await asyncio.gather(*tasks)

async def func_a():
    print("func a")
    await func_b()
    await func_b_v2()
    

async def main():
    await func_a()
    
if __name__ == "__main__":
    asyncio.run(main())

我遇到的问题是,如果在

traceback.print_stack()
调用中由
func_b
func_b_v2
调用,
await asyncio.gather
会产生相同的结果。

回溯看起来像这样:

File "test.py", line 28, in <module>
  asyncio.run(main())
File "asyncio/runners.py", line 190, in run
  return runner.run(main)
File "asyncio/runners.py", line 118, in run
  return self._loop.run_until_complete(task)
File "asyncio/base_events.py", line 640, in run_until_complete
  self.run_forever()
File "asyncio/base_events.py", line 607, in run_forever
  self._run_once()
File "asyncio/base_events.py", line 1919, in _run_once
  handle._run()
File "asyncio/events.py", line 80, in _run
  self._context.run(self._callback, *self._args)
File "test.py", line 6, in func_c
  traceback.print_stack()

手动将回溯从一个函数传递到另一个函数并不理想,因为我的代码库中的 func_c 有效地用于记录结果,但随后能够跟踪该结果的回溯。

我尝试过使用其他方式同时调用多个任务 例如 使用

asyncio.create_task
并使用 for 循环来等待这些任务。这会产生类似的结果。

类似的问题没有帮助: 协程的Python回溯(不使用

asyncio.gather
函数)

python python-asyncio traceback
1个回答
0
投票

恐怕不行。协程并不是通常意义上的“调用”。相反,创建了一个任务并由调度程序运行它。 函数返回给调用者,返回地址存储在堆栈中,这就是堆栈回溯显示这种关系的原因。 OTOH 任务不会返回给调用者。一般来说,任务可以在异步程序中的任何地方创建,并且创建的任务也可以在任何地方等待,甚至可以在多个地方等待。堆栈上没有与所需信息的链接。

作为一种解决方法(某种程度上),您可以为任务命名(或为其指定特定的上下文)。

async def func_b(): print("func b") tasks = [ asyncio.create_task(func_c(), name="created in func_b") for _ in range(3)] await asyncio.gather(*tasks)

	
© www.soinside.com 2019 - 2024. All rights reserved.