8.16. Zusammenfassung

Du hast die API von asyncio durchgearbeitet – die Bausteine, die ein Skript benötigt, um mehrere Aufgaben gleichzeitig auf einer einzelnen CPU auszuführen:

  • Kooperative Planung – das Modell, auf dem der Rest des Moduls aufbaut. Die laufende Coroutine hat den Loop für sich allein, bis sie awaitet; Wechsel finden nur an diesen Awaits statt.

  • Coroutinen und Tasksasync def definiert eine Arbeitseinheit; asyncio.create_task() plant eine davon nebenläufig ein und gibt einen Task zurück, auf den die Anwendung später warten kann, den sie abbrechen oder identifizieren kann.

  • Der Event-Loop – die Engine, die Coroutinen und Tasks ausführt. asyncio.run() ist der einzige Einstiegspunkt, den die meisten Skripte benötigen; die Klasse Loop stellt den Rest für die seltenen Fälle bereit, die ihn brauchen.

  • Koordinationgather() für Fan-out und Fan-in, wait_for() für Fristen, Task.cancel und das Aufräummuster der finally-Klausel, Ausnahmeweiterleitung durch Tasks und Gather-Aufrufe sowie der Hook für den Ausnahmehandler des Loops.

  • SynchronisationsprimitivenEvent zur Signalisierung zwischen Coroutinen, Lock zur Serialisierung des Zugriffs auf eine gemeinsam genutzte Ressource über Awaits hinweg und ThreadSafeFlag zum Aufwecken eines asyncio-Tasks aus einem Interrupt-Handler.

  • Eigene async-Objekte – die Sprach-Hooks, die es Anwendungsklassen ermöglichen, sich in asyncio-Idiome einzuklinken. __await__ für Objekte, die selbst das Ziel von await sind, __aiter__ / __anext__ für async for und __aenter__ / __aexit__ für async with.

  • Einzelbild-Erfassung – der Wrapper, der csi.CSI.snapshot() in eine await-freundliche Coroutine verwandelt, sodass eine Erfassungsschleife neben anderer asyncio-Arbeit läuft.

  • Fallstricke – vergessene awaits, enge Schleifen ohne Abgabe, verschluckte Abbrüche, gemeinsam genutzter Zustand, der über Awaits hinweg verändert wird, und die übrigen asyncio-spezifischen Fallen.

Das reicht aus, um Programme zu schreiben, die Kameraarbeit, Hardware-I/O und nebenläufige Hintergrundarbeit auf demselben Loop mischen.

8.16.1. Diese Referenz später nutzen

Behandle die asyncio-Kapitel als Referenzmaterial; zurückzukommen, um die Struktur von async with oder das genaue Verhalten von gather() bei einem Fehler eines Geschwister-Tasks nachzuschlagen, ist die beabsichtigte Verwendung. Die Referenzseite des asyncio-Moduls listet jede Funktion und Klasse an einem Ort auf, wenn die Frage nur lautet „wie lautet der genaue Name dieses Aufrufs“.

Für reichhaltigere Primitiven, die auf dem Modul aufbauen – Semaphoren, Queues, Barrieren und eine umfangreiche Sammlung anwendungsorientierter Helfer – ist das Repository peterhinch/micropython-async die standardmäßige, von der Community gepflegte Quelle.

8.16.2. Wie es von hier aus weitergeht

Netzwerke sind das nächste große Thema. asyncio.open_connection(), asyncio.start_server() und die Klasse Stream sind die Art, wie ein asyncio-Skript aus einer Coroutine heraus mit dem Rest des Netzwerks spricht, zusammen mit den darunterliegenden Modulen network und socket. Alles, was du über await, Task, Abbruch und die Synchronisationsprimitiven gelernt hast, lässt sich direkt übertragen.