asyncio.Task.all_tasks() 的不同行为

Different behaviour of asyncio.Task.all_tasks()

第一个例子:

import asyncio

async def req():
    print('request')
    await asyncio.sleep(1)

async def run():
    print(len(asyncio.Task.all_tasks()))
    asyncio.ensure_future(req())
    print(len(asyncio.Task.all_tasks()))
    await asyncio.sleep(2)
    print(len(asyncio.Task.all_tasks()))

loop = asyncio.get_event_loop()
loop.run_until_complete(run())

结果是:

1
2
request
1

第二个例子:

import asyncio

async def req():
    print('request')
    await asyncio.sleep(1)

async def run():
    print(len(asyncio.Task.all_tasks()))
    t = asyncio.ensure_future(req())
    print(len(asyncio.Task.all_tasks()))
    await t
    print(len(asyncio.Task.all_tasks()))

loop = asyncio.get_event_loop()
loop.run_until_complete(run())

结果是:

1
2
request
2

那么,为什么在第一个示例中最后调用 asyncio.Task.all_tasks() return 1 而在第二个示例中它是 return 2? 换句话说,为什么在第一个示例中,包装 req() 的任务从事件循环的一组所有任务中删除,以及为什么第二个示例不正确。

destroyed 时,任务已从 all_tasks() 中删除。

添加一个del语句:

    [...]
    await t
    del t
    print(len(asyncio.Task.all_tasks()))

它将产生:

1
2
request
1