这个问题可以用这个例子来概括:
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
函数)
恐怕不行。协程并不是通常意义上的“调用”。相反,创建了一个任务并由调度程序运行它。 函数返回给调用者,返回地址存储在堆栈中,这就是堆栈回溯显示这种关系的原因。 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)