Что более эффективно - использовать create_task () или gather ()?

Я все еще изучаю основы асинхронного питона, и некоторые вещи меня смущают.

import asyncio
loop=asyncio.get_event_loop()
for variation in args:
    loop.create_task(coroutine(variation))
loop.run_forever()

Кажется очень похожим на это

import asyncio
loop=asyncio.get_event_loop()
loop.run_forever(
    asyncio.gather(
        coroutine(variation_1),
        coroutine(variation_2),
        ...))

Они могут делать то же самое, но это не кажется полезным, так в чем разница?

run_forever не принимает аргументов. Ваш второй пример должен использовать run_until_complete.
dirn 09.09.2018 18:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
1
4 172
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как упоминалось в комментариях, ваш второй пример должен использовать run_until_complete, а не run_forever.

They might do the same thing, but that doesn't seem useful, so what's the difference?

asyncio.gather - это конструкция более высокого уровня.

  • create_task отправляет сопрограмму в цикл событий, эффективно позволяя ей работать «в фоновом режиме» (при условии, что сам цикл событий активен). Как следует из названия, он возвращает задача, дескриптор выполнения сопрограммы, что наиболее важно, предоставляя возможность Отмена. Вы можете создать любое количество таких задач в цикле событий, и все они будут выполняться до их соответствующего завершения.

  • asyncio.gather используется, когда вас действительно интересует полученные результаты сопрограмм, которые вы создали. Он порождает их, как если бы с create_task, позволяя им работать параллельно, но также ожидает их завершения, а затем возвращает их соответствующие результаты (или вызывает исключение, если какой-либо из них вызвал один).

Например, если у вас есть сопрограмма download, которая загружает URL-адрес и возвращает его содержимое, и вы загружаете список URL-адресов, gather позволяет вам сопоставить URL-адреса с их данными:

url_list = [...]
data_list = await asyncio.gather(*[download(url) for url in url_list]

# url_list and data_list now have matching elements, so this works:
for url, data in zip(url_list, data_list):
    ...

Сделать это с помощью только create_task было бы намного сложнее.

gather также позволяет отменить все задачи одной командой cancel().
Aviah Laor 11.10.2020 04:11

@AviahLaor Да, но будьте осторожны, потому что бывают случаи, когда это не работает как ожидалось.

user4815162342 15.12.2020 21:36

Другие вопросы по теме