это стандартный способ выполнения ввода-вывода параллельно с сопрограммами. Кроме того, я понял, что мой пример кода неправильно использует aiohttp.
ой пример: мне нужно сделать два не связанных HTTP-запроса параллельно. Какой самый простой способ сделать это? Я ожидаю, что это будет так:
async def do_the_job():
with aiohttp.ClientSession() as session:
coro_1 = session.get('http://httpbin.org/get')
coro_2 = session.get('http://httpbin.org/ip')
return combine_responses(await coro_1, await coro_2)
Другими словами, я хочу инициировать операции ввода-вывода и ждать их результатов, чтобы они эффективно работали параллельно. Это может быть достигнуто сasyncio.gather
:
async def do_the_job():
with aiohttp.ClientSession() as session:
coro_1 = session.get('http://example.com/get')
coro_2 = session.get('http://example.org/tp')
return combine_responses(*(await asyncio.gather(coro_1, coro_2)))
Далее я хочу иметь некоторую сложную структуру зависимостей. Я хочу начать работу, когда у меня есть все предпосылки для этого, и получать результаты, когда мне нужны результаты. Здесь помогаетasyncio.ensure_future
которая отделяет задачу от сопрограммы, которая управляется циклом событий отдельно:
async def do_the_job():
with aiohttp.ClientSession() as session:
fut_1 = asyncio.ensure_future(session.get('http://httpbin.org/ip'))
coro_2 = session.get('http://httpbin.org/get')
coro_3 = session.post('http://httpbin.org/post', data=(await coro_2)
coro_3_result = await coro_3
return combine_responses(await fut_1, coro_3_result)
Правда ли, что для достижения параллельного неблокирующего ввода-вывода с сопрограммами в моем логическом потоке я должен использовать либоasyncio.ensure_future
или жеasyncio.gather
(который на самом деле используетasyncio.ensure_future
)? Есть ли менее "многословный" способ?
Правда ли, что разработчики обычно должны думать, какие сопрограммы должны стать отдельными задачами, и использовать вышеупомянутые функции для достижения оптимальной производительности?
Есть ли смысл в использовании сопрограмм без нескольких задач в цикле обработки событий?
Насколько «тяжелыми» являются задачи цикла событий в реальной жизни? Конечно, они «легче», чем потоки или процессы ОС. В какой степени я должен стремиться к минимально возможному числу таких задач?