在Python的asyncio模块中,当一个任务被取消时,默认情况下不会自动取消其子任务,这可能会导致意外的行为或资源泄漏。为了解决这个问题,可以使用try/finally语句块和asyncio的shield()
函数。
示例代码如下:
import asyncio
async def child_task():
try:
while True:
print("child task running")
await asyncio.sleep(1)
except asyncio.CancelledError:
print("child task cancelled")
raise
async def parent_task():
child = asyncio.create_task(child_task())
try:
while True:
print("parent task running")
await asyncio.sleep(1)
finally:
child.cancel() # 手动取消子任务,以防止意外泄漏
async def main():
parent = asyncio.create_task(parent_task())
await asyncio.sleep(5)
parent.cancel() # 取消父任务
asyncio.run(main())
在这个示例中,当执行parent.cancel()
时,父任务被取消,并调用其finally
块中的代码来手动取消子任务。shield()
函数也可以用于确保子任务不会被取消,但应该谨慎使用,因为它可能会导致崩溃或其他意外结果。