Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Асинхронное программирование питон

Олег Дипникович Профи (664), открыт 3 часа назад
Вопросы по коду.
1) в main() как работает event_loop? Он сначала построчно добавляет каждую задачу в event_loop и только потом, когда добавил, в том же порядке начинает их выполнять? То есть смотрит, что было добавлено первее, начинает выполнять, затем откладывает на время, в списке задач переходит к следующему методу и тд? А как только закончил выполнение определенной функции и видит, что уже прошло время, запускает снова нужную функцию. Всё верно или нет? Я просто не понимаю, он сначала все строки читает: заносит задачи в список, или он прочитал строку и сразу начал выполнение этой задачи.

2) Как работает asyncio .run? По сути, он добавляет в event_loop задачи, которые находятся в main(). И для задач, между которыми он может переключаться, await определена. Но что касается самого main()? Это ведь никакая не задача и в список задач event_loop его же не заносит? Или заносит..? То есть в run мы помещаем функцию, которая передастся как задача. Просто в эту задачу мы помещаем набор других задач, так?

В общем. Суть в том, что я не понял, как работает await. Если рассматривать main() как задачу аналогично есть вопросы: А что делает сам await? Вот выполняется первая задача asyncio.create_task(one()); Он доходит до await в one(), метод на время захлопывается? А как он потом вызывается, если основная задача - это main()? Или предусмотрена такая встройка функций? Если функция в main() - async, то она воспринимается как отдельная задача? Если да, то в целом всё ясно: начинается задача main(), выполняется первая строчка кода. one() - асинхронка, а значит добавляется отдельная задача в event_loop. Причём ставится на паузу пока что. Но у нас в event_loop из активных задач есть всё тот же main(), поэтому возвращаемся к main() и продолжаем исполнение. Так что ле?



 import asyncio 
import time

async def one():
print("Start one")
await asyncio.sleep(1)
print("Stop one")

async def two():
print("Start two")
await asyncio.sleep(2)
print("Stop two")

async def three():
print("Start three")
await asyncio.sleep(3)
print("Stop three")

async def main():
asyncio.create_task(one())
asyncio.create_task(two())
await asyncio.create_task(three())

if __name__=='__main__':
start = time.time()
asyncio.run(main())
print(time.time()-start)
2 ответа
Resurce InheiT Профи (969) 3 часа назад
asyncio.run запускает event loop и создает главную задачу из main().

asyncio.create_task создает и запускает новые задачи, добавляя их в event loop.

await приостанавливает выполнение текущей корутины и отдает управление event loop-у.

Event loop следит за задачами, переключаясь между ними при await и возобновляя их выполнение.
Олег ДипниковичПрофи (664) 3 часа назад
asyncio.create_task создает и запускает новые задачи
То есть строка asyncio.create_task(one()) запускает метод one() и добавляет его в event_loop да?

А как работает при этом основная задача main() ? При await во вторичных задачах(которые не основные) нас возвращает в основную задачу: в метод main(), на то же место и мы продолжаем читать, да?
Resurce InheiT Профи (969) Олег Дипникович, Верно. asyncio.create_task(one()) создает задачу для one() и планирует ее выполнение в event loop. Основная задача main() продолжает выполняться до await. При await в one() управление передается event loop-у, который смотрит, какие еще задачи готовы к выполнению. Как только one() завершит ожидание (например, завершится asyncio.sleep), event loop возобновит ее с того места, где она была приостановлена. Если в main() есть await, то она также приостанавливается, отдавая управление другим задачам. Когда все await в main() завершатся, она тоже закончит выполнение.
Senior Backend Developer Оракул (80069) 3 часа назад
Если коротко event loop - это как шахматный гроссмейстер, который играет с несколькими игроками (корутинами) одновременно, логика точно такая же, await говорит ему, что он может переключиться на другую задачу пока выполняется эта. То есть гроссмейстер во время await сделал ход и передает ход игроку, как только игрок закончил свой ход он ждет пока гроссмейстер закончит свои текущие задачи и вернется к нему.
Похожие вопросы