调用图内省¶
源代码: Lib/asyncio/graph.py
asyncio具有强大的运行时调用图自检实用程序,可以跟踪正在运行的 协程 或 任务 或挂起的 future 的整个调用图。这些实用程序和底层机制可以在Python程序中使用,也可以由外部分析器和调试器使用。
Added in version 3.14.
- asyncio.print_call_graph(future=None, /, *, file=None, depth=1, limit=None)¶
打印当前任务或提供的
Task
或Future
的异步调用图。此函数从顶部帧开始打印条目,并向下打印到调用点。
该函数接收一个可选的 future 参数。如果没有传入,则使用当前运行的任务。
如果在 当前任务 上调用该函数,可选的仅限关键字 depth 参数可用于从堆栈顶部跳过指定的帧数。
如果提供了可选的仅限关键字 limit 参数,则结果图中的每个调用堆栈将被截断,以最多包含``abs(limit)``项。如果 limit 为正数,则剩下的条目是最接近调用点的。如果 limit 为负数,则保留最上面的项。如果 limit 省略或为``None``,则所有条目都存在。如果 limit 为``0``,则根本不打印调用堆栈,只打印“awaited by”信息。
如果 file 省略或为``None``,该函数将打印到
sys.stdout
。示例:
以下 Python 代码:
import asyncio async def test(): asyncio.print_call_graph() async def main(): async with asyncio.TaskGroup() as g: g.create_task(test(), name='test') asyncio.run(main())
将打印:
* Task(name='test', id=0x1039f0fe0) + Call stack: | File 't2.py', line 4, in async test() + Awaited by: * Task(name='Task-1', id=0x103a5e060) + Call stack: | File 'taskgroups.py', line 107, in async TaskGroup.__aexit__() | File 't2.py', line 7, in async main()
- asyncio.format_call_graph(future=None, /, *, depth=1, limit=None)¶
类似于
print_call_graph()
,但返回一个字符串。如果 future 为None
并且没有当前任务,则该函数返回一个空字符串。
- asyncio.capture_call_graph(future=None, /, *, depth=1, limit=None)¶
捕获当前任务或提供的
Task
或Future
的异步调用图。该函数接收一个可选的 future 参数。如果没有传入,则使用当前运行的任务。如果当前没有任务,该函数返回``None``。
如果在 当前任务 上调用该函数,可选的仅限关键字 depth 参数可用于从堆栈顶部跳过指定的帧数。
返回``FutureCallGraph``数据类对象。
FutureCallGraph(future, call_stack, awaited_by)
FrameCallGraphEntry(frame)
其中 frame 是调用栈中常规Python函数的帧对象。
底层实用工具函数¶
要自检一个异步调用图,asyncio 需要控制流结构的配合,比如 shield()
或 TaskGroup
。 任何时候涉及到具有底层 API (如 Future.add_done_callback()
) 的中间 Future
对象时,都应该使用以下两个函数来通知 asyncio 这些中间 Future 对象是如何与它们包装或控制的任务连接的。
- asyncio.future_add_to_awaited_by(future, waiter, /)¶
future 被 waiter 等待的记录。
future 和 waiter 都必须是
Future
或Task
或它们的子类的实例,否则该调用将不起作用。调用
future_add_to_awaited_by()
必须随后使用相同的参数最终调用future_discard_from_awaited_by()
函数。