Обычный шаблон с asyncio, подобный показанному здесь , состоит в добавлении коллекции сопрограмм в список, а затем asyncio.gather
их.
Например:
async def some_task(i):
# Do something asynchronously with i
tasks = [some_task(i) for i in range(100)]
loop.run_until_complete(asyncio.gather(**tasks))
Здесь порядок выполнения этого кода таков, что ни одна из задач не выполняется, пока мы формируем список. Мы добавляем задачу 1 в список, затем задачу 2 и т. Д. И , затем добавляем задачи 1-100 в цикл событий.
Однако я хочу, чтобы само создание задачи было частью цикла событий. Я хочу, чтобы задача 1 планировалась сразу после ее создания, а затем, когда задача ожидает чего-то в другом потоке, вернитесь к созданию задачи и создайте задачу 2 и добавьте ее в цикл событий.
Полагаю, это улучшит параллелизм моего асинхронного кода. Это возможно?
Например, моей первой мыслью было бы поместить создание задач в сопрограмму и планировать задачи по мере их создания:
async def some_task(i):
# Do something asynchronously with i
async def generate_tasks(loop):
tasks = []
for i in range(100):
task = loop.create_task(some_task(i))
tasks.append(loop)
await asyncio.gather(**tasks)
loop.run_until_complete(generate_tasks())
Однако, поскольку мой generate_tasks
никогда не использует await
, выполнение никогда не передается обратно в цикл обработки событий, поэтому весь generate_tasks
будет выполняться до того, как some_task()
будет запущен вообще.
Но тогда, если я await
выполню каждую задачу по мере ее создания, она будет ждать завершения каждой задачи, прежде чем перейти к следующей задаче, не давая мне никакого параллелизма вообще!
async def generate_tasks(loop):
tasks = []
for i in range(100):
await some_task(i)
loop.run_until_complete(generate_tasks())