You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用asyncio.create_task创建的任务为何无法被垃圾回收?

为什么用asyncio.create_task()创建的任务没被垃圾回收?

以下是测试代码:

import asyncio
import gc

c = 0


async def run():
    global c
    try:
        while True:
            await asyncio.sleep(1)
            c += 1
    except Exception as e:
        print(e)


async def main():
    task = asyncio.create_task(run())
    del task
    while True:
        await asyncio.sleep(0.2)
        print(c)
        gc.collect()


asyncio.run(main())

预期结果:

0
0
0
asyncio.CancelledError

实际结果:

0
0
0
0
0
1
1
1
1
1
..
101
101
101
101
101
102
...

原因分析

问题出在asyncio.create_task()的运行机制上:当调用这个函数创建任务时,asyncio的事件循环会自动持有该任务的强引用,并将其加入待执行任务队列。哪怕你在main函数里删除了task变量,事件循环的引用依然存在,垃圾回收器无法回收这个任务,所以run()里的无限循环会持续执行,c也就不断累加。

说白了:你删的只是自己手里的任务引用,事件循环还攥着任务不放,任务自然不会停止。

实现预期结果的修改方法

如果想要任务被取消并触发CancelledError,需要主动调用任务的cancel()方法,而非单纯删除变量。修改后的main函数如下:

async def main():
    task = asyncio.create_task(run())
    task.cancel()  # 主动取消任务
    del task
    while True:
        await asyncio.sleep(0.2)
        print(c)
        gc.collect()

修改后,任务会被立即取消,run()里的异常会被捕获并打印,c会一直保持0,符合预期结果。

内容的提问来源于stack exchange,提问作者mq7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:09:59