Зачем нам нужен Asyncio.sleep для запуска цикла? - PullRequest
1 голос
/ 31 марта 2019

В этом документе Asyncio мы видим, что он использует await asyncio.sleep(1) для задержки 1 секунды, а затем отменяет задачу.

И я пытаюсь изменить его на await asyncio.sleep(0),это тоже хорошо работает.

Но когда я пытаюсь удалить await asyncio.sleep(1), программа, похоже, не войдет в func cancel_me.Так что это просто появляется main(): cancel_me is cancelled now в кли.

В чем причина?

1 Ответ

1 голос
/ 31 марта 2019

asyncio сопрограммы не выполняются сами по себе, они выполняются циклом событий .

Цикл событий получает управление на asyncio.run и начинает выполнять некоторую сопрограмму.Когда поток выполнения достигает чего-то блокирующего, например await asyncio.sleep() или await future, он возвращает управление обратно в цикл обработки событий.Это позволяет циклу событий запускать или возобновлять выполнение чего-то еще.

Посмотрите на пример и рисунок здесь , чтобы увидеть его на простом примере.


In пример о cancel() происходит следующее:

  1. await asyncio.sleep(0), а также 1 вернет управление в цикл событий
  2. Цикл событий начнетexecute cancel_me()
  3. cancel_me() в итоге наткнется на что-то блокирующее и вернет управление обратно в цикл событий
  4. Цикл событий возобновит выполнение main()
  5. main()пометит задачу, которая будет отменена, с помощью task.cancel() и ждет ее отмены с помощью await task

Если у вас, однако, нет asyncio.sleep() на первом этапе, поток выполнения даже не достигнет cancel_me() потому что цикл обработки событий никогда не получал контроль между созданием и отменой задачи.Когда цикл обработки достигает значения await task, он видит, что задача никогда не запускалась, и помечает для отмены: нет смысла запускать ее сейчас.

...