8.3. Smyčka událostí#

Smyčka událostí je engine, který asyncio běží pod tím vším. Udržuje seznam každé úlohy v programu, požádá každou z nich, aby běžela až do svého nejbližšího await, a přejde na další připravenou úlohu. Když nejsou žádné připravené úlohy, čeká — toto skutečné čekání je to, co uvolňuje procesor, aby firmware mohl běžet jiné věci a aby se mohla uplatnit úsporná uspání — dokud nebude dostupné něco, na co úloha čekala, a poté tuto úlohu obnoví. A tak stále dokola.

Většina aplikací se smyčkou nikdy přímo neinteraguje. Smyčka je důsledkem volání asyncio.run(); aplikace píše korutiny, plánuje je jako úlohy a smyčka udělá zbytek.

8.3.1. Co asyncio.run() ve skutečnosti dělá#

Jediné volání:

asyncio.run(main())

je zkratkou za delší sekvenci, kterou smyčka spravuje jménem aplikace:

  1. Vytvoří smyčku událostí, pokud ještě neexistuje.

  2. Zabalí dodanou korutinu do úlohy a naplánuje ji jako vrcholový vstupní bod smyčky.

  3. Spustí smyčku — postupně prochází připravené úlohy, čeká, když žádná není připravena, obnovuje úlohy, když se jejich awaity dokončí — dokud se vrcholová úloha nevrátí nebo nevyvolá výjimku.

  4. Zruší veškeré úlohy, které aplikace vytvořila a které stále běží.

  5. Vrátí to, co vrátila vrcholová korutina (nebo znovu vyvolá to, co vyvolala).

8.3.2. Jedna smyčka na program#

Asyncio v MicroPythonu má jednu smyčku událostí, tečka. Neexistuje vytváření nové smyčky a neexistuje vnořování jedné smyčky do druhé. Volání asyncio.run() zevnitř korutiny, která již běží na smyčce, je chybou; smyčka už tam je a korutina prostě potřebuje awaitovat to, co chtěla spustit.

V praxi je pravidlo stejné jako závěrečný řádek předchozí stránky: na program připadá přesně jedno volání asyncio.run(), na vrcholu, za nímž je jediná async def main(). Vše ostatní žije uvnitř main.

8.3.3. Přímý přístup ke smyčce#

Pro vzácné případy, kdy aplikace potřebuje sáhnout na smyčku samotnou — většinou diagnostika a obslužné rutiny výjimek — vrací asyncio.get_event_loop() objekt Loop. Odtud může aplikace nainstalovat vlastní obslužnou rutinu výjimek, zkoumat, co smyčka dělá, nebo (velmi výjimečně) volat create_task() přímo namísto asyncio.create_task() (jde o stejnou operaci).

Kompletní sadu metod, které Loop poskytuje — run_forever(), stop(), set_exception_handler() a zbytek — popisuje stránka o řízení smyčky později v této sekci. Do té doby je asyncio.run(main()) vše, co aplikace potřebuje.