Top.Mail.Ru
Ответы

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

Вопросы по коду.
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() и продолжаем исполнение. Так что ле?



123456789101112131415161718192021222324252627
 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) 
По дате
По рейтингу
Аватар пользователя
Оракул
6мес

Если коротко event loop - это как шахматный гроссмейстер, который играет с несколькими игроками (корутинами) одновременно, логика точно такая же, await говорит ему, что он может переключиться на другую задачу пока выполняется эта. То есть гроссмейстер во время await сделал ход и передает ход игроку, как только игрок закончил свой ход он ждет пока гроссмейстер закончит свои текущие задачи и вернется к нему.

Аватар пользователя
Мастер
6мес

asyncio.run запускает event loop и создает главную задачу из main().

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

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

Event loop следит за задачами, переключаясь между ними при await и возобновляя их выполнение.