Count active tasks in event loop

2019-06-22 09:02发布

问题:

How can I find out how many active tasks in the event loop? In documentation I find only asyncio.Task.all_tasks() but it's simple incremental counter:

import asyncio


async def coro():
    await asyncio.sleep(1)


async def main():
    tasks = []
    print('Tasks count: ', len(asyncio.Task.all_tasks()))
    for idx in range(3):
        task = asyncio.ensure_future(coro())
        tasks.append(task)
        print('Tasks count: ', len(asyncio.Task.all_tasks()))
    await asyncio.gather(*tasks)
    print('Tasks count: ', len(asyncio.Task.all_tasks()))


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

Output:

Tasks count:  1
Tasks count:  2
Tasks count:  3
Tasks count:  4
Tasks count:  4

Expected output:

Tasks count:  1
Tasks count:  2
Tasks count:  3
Tasks count:  4
Tasks count:  1

回答1:

all_tasks returns all the registered tasks, including the finished ones. You can simply filter the tasks by done() to get the active ones:

import asyncio


async def coro():
    await asyncio.sleep(1)


async def main():
    tasks = []
    print('Tasks count: ', len(asyncio.Task.all_tasks()))
    for idx in range(3):
        task = asyncio.ensure_future(coro())
        tasks.append(task)
        print('Tasks count: ', len(asyncio.Task.all_tasks()))
    await asyncio.gather(*tasks)
    print('Tasks count: ', len(asyncio.Task.all_tasks()))
    print('Active tasks count: ', len(
        [task for task in asyncio.Task.all_tasks() if not task.done()])
    )

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

Which outputs:

Tasks count:  1
Tasks count:  2
Tasks count:  3
Tasks count:  4
Tasks count:  4
Active tasks count:  1


回答2:

In Python 3.7+ there is a asyncio.all_tasks() method which returns the unfinished tasks for the current running loop.

So this simplifies to:

count_active_tasks = len(asyncio.all_tasks())