Почему все задачи выполняются в asyncio.wait (), когда я четко указываю, что хочу выполнить только первую?

0
задан 917k 14 April 2019 в 11:59
поделиться

1 ответ

return_when=FIRST_COMPLETED не гарантирует, что будет выполнена только одна задача. Это гарантирует, что ожидание завершится, как только задача завершится, но вполне возможно, что другие задачи завершатся «в одно и то же время», что для asyncio означает одну и ту же итерацию цикла событий. Рассмотрим, например, следующий код:

async def noop():
    pass

async def main():
    done, pending = await asyncio.wait(
        [noop(), noop(), noop()], return_when=asyncio.FIRST_COMPLETED)
    print(len(done), len(pending))

asyncio.run(main())

Это печатает 3 0, так же, как ваш код. Почему?

asyncio.wait делает две вещи: отправляет сопрограммы в цикл обработки событий и устанавливает обратные вызовы, чтобы уведомить его о завершении любого из них. Однако сопрограмма noop не содержит await, поэтому ни один из вызовов noop() не приостанавливается, каждый просто делает свое дело и немедленно возвращается. В результате все три экземпляра сопрограммы заканчиваются в одном и том же проходе цикла событий. wait затем сообщают, что все три сопрограммы закончились, о чем должным образом сообщается.

Если вы измените noop на ожидание случайного сна, например, измените pass на await asyncio.sleep(0.1 * random.random()), вы получите ожидаемое поведение. С await сопрограммы больше не завершаются в одно и то же время, и wait сообщит о первом, как только он его обнаружит.

Это показывает истинную причину проблемы с вашим кодом: _perform_query не ждет . Это указывает на то, что вы не используете асинхронную базовую библиотеку или используете ее неправильно. Вызов SearchSubtitles, скорее всего, просто блокирует цикл обработки событий, который , по-видимому, работает в тривиальных тестах, но нарушает важные асинхронные функции, такие как одновременное выполнение задач.

0
ответ дан user4815162342 14 April 2019 в 11:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: