asyncio.all_tasks返回当前事件循环中所有未完成的Task对象集合(set),包括运行中、已调度未开始或已暂停但未取消的任务,不包含协程对象或已结束/已取消未清理的任务。

asyncio.all_tasks 返回什么?
asyncio.all_tasks 返回当前事件循环中所有 未完成 的 Task 对象集合(set),包括正在运行、已调度但未开始、或已暂停但尚未取消的任务。它不包含普通协程对象(coroutine),也不包含已结束(done)或已被取消(cancelled)但尚未被清理的任务。
注意:在 Python 3.9+ 中,asyncio.all_tasks 默认作用于当前线程的当前事件循环;若事件循环未运行或已关闭,会抛出 RuntimeError。
如何安全调用 asyncio.all_tasks?
直接调用 asyncio.all_tasks() 在非异步上下文(比如同步函数里)可能报错,因为此时可能没有运行中的事件循环。常见错误是:RuntimeError: no running event loop。
- 在协程内部调用时,确保事件循环已启动且未关闭 —— 通常用
asyncio.run()或手动loop.run_until_complete()启动 - 想在任意位置检查任务,先用
asyncio.get_running_loop()判断是否存在运行中循环,再调用all_tasks - 若需跨线程访问(如从后台线程查主线程的任务),不能直接调用 ——
all_tasks只对当前线程的当前循环有效
示例(安全写法):
立即学习“Python免费学习笔记(深入)”;
import asyncio
<p>async def monitor():</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill8054" title="python-parallelization"><img
src="https://img.php.cn/upload/skill/000/000/081/179181013081932.jpg" alt="python-parallelization" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill8054" title="python-parallelization">python-parallelization</a>
<p>将顺序 Python 代码转换为并行/并发实现,用于在需要并行化 Python 代码、提升性能时使用。</p>
</div>
<a href="/xiazai/skill8054" title="python-parallelization" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><h1>✅ 安全:在协程中,loop 正在运行</h1><pre class="brush:php;toolbar:false;">tasks = asyncio.all_tasks()
print(f"当前活跃任务数:{len(tasks)}")
for t in tasks:
print(f" - {t.get_coro().__name__} (done={t.done()}, cancelled={t.cancelled()})")❌ 错误:不在协程中,loop 可能未运行
asyncio.all_tasks() # RuntimeError!
all_tasks() 和 current_task() 有什么区别?
asyncio.current_task() 只返回当前正在执行的 Task(即调用它的那个协程所绑定的任务),而 asyncio.all_tasks() 返回全部活跃任务 —— 包括你自己、其他并发协程、甚至后台 create_task 启动的守护任务。
-
current_task()可能为None(比如在非 Task 环境中,如普通线程或回调) -
all_tasks()总是返回一个set,哪怕为空;但若事件循环未运行,会抛异常 - 调试时常用组合:
current_task() in asyncio.all_tasks()判断当前是否在活跃任务中
性能上,all_tasks() 是 O(1) 集合读取,开销极小;但频繁调用本身不解决任务泄漏问题,只是观测手段。
为什么看到太多任务不消失?常见泄漏原因
调用 asyncio.all_tasks() 发现任务数持续增长,大概率是任务没被正确 await 或被意外丢弃。典型场景:
- 用了
asyncio.create_task()但没保存引用,也没 await 它 —— 任务会继续运行,但你失去了控制权 - 协程抛出未捕获异常后,任务状态变为
done()但仍在all_tasks()中,直到被事件循环清理(通常在下一次循环迭代) - 使用了
asyncio.ensure_future()+ 回调模式,但回调里没处理异常,导致任务卡在“已完成但未取结果”状态 - 在
finally块中忘记await task.cancel()或task.cancel()后没await task
真正要释放任务,不是靠“不引用”,而是确保它结束(done/cancelled)并被事件循环回收 —— 这通常需要显式 await 或等待其自然完成。
任务对象本身很小,但背后可能持有 socket、文件句柄或闭包变量,长期滞留会引发资源泄漏。别只盯着 all_tasks() 数量,重点看哪些任务本该结束却一直 pending。

















