EMZETT.
Login

asyncio: Nebenläufigkeit in Python ohne Threads

Kurz: Mit asyncio laufen viele wartende Aufgaben (Netzwerk, Dateien) in einem einzigen Thread nebeneinander, indem sie sich beim Warten gegenseitig Platz machen.

Genauer: Viele Programme warten die meiste Zeit: auf eine Antwort vom Server, auf die Festplatte, auf die Datenbank. Statt für jede Anfrage einen Thread zu starten, nutzt asyncio kooperatives Multitasking: Ein Event Loop führt Coroutinen aus, und jede gibt beim Warten (await) die Kontrolle ab, sodass eine andere weiterlaufen kann.

Im Detail

Grundbegriffe

  • Coroutine: eine Funktion mit async def, die pausieren kann.
  • await: pausiert die Coroutine, bis das Ergebnis bereit ist, und lässt den Event Loop andere Arbeit erledigen.
  • Task: eine eingeplante Coroutine, die nebenläufig läuft (asyncio.create_task).
  • Event Loop: Schleife, die Aufgaben verwaltet und fortsetzt (asyncio.run).

Beispiel

import asyncio
 
async def hole(name, sekunden):
    await asyncio.sleep(sekunden)      # simuliert Warten auf das Netz
    return f"{name} fertig"
 
async def main():
    ergebnisse = await asyncio.gather(
        hole("A", 2), hole("B", 1), hole("C", 3)
    )
    print(ergebnisse)                  # nach ca. 3 s, nicht nach 6 s
 
asyncio.run(main())

Die drei Aufgaben warten gleichzeitig. Die Gesamtzeit entspricht der längsten, nicht der Summe.

Wann es hilft, wann nicht

Hilfreich bei I/O-gebundenen Aufgaben: viele HTTP-Anfragen, Datenbankzugriffe, Websockets, Webserver (FastAPI, aiohttp). Bei rechenintensiven Aufgaben bringt es nichts, da nur ein Thread rechnet; dafür nutzt man multiprocessing oder concurrent.futures.ProcessPoolExecutor. Blockierende Aufrufe wie time.sleep() oder requests.get() innerhalb einer Coroutine blockieren den ganzen Event Loop; verwende asyncio.sleep und asynchrone Bibliotheken (httpx, aiohttp) oder asyncio.to_thread.

Fallen

Vergessenes await erzeugt nur ein Coroutine-Objekt, aber keine Ausführung. Fehler in nicht abgewarteten Tasks gehen leicht unter, nutze TaskGroup (Python 3.11+) für sauberes Fehlerhandling. Beende lange Tasks mit Zeitlimits (asyncio.timeout). Das gleiche Prinzip (async/await) kennst du aus JavaScript, C# und Rust.

Siehe auch: async/await, Event Loop, Nebenläufigkeit