Free-threaded Python – Top oder Flop?¶

Python 3.14 kommt in wenigen Wochen mit einigen wichtigen Änderungen in Bezug auf auf Parallelität:
Beide Features stellen Fortschritte in der Verwendung von Python zur Ausführung von parallelem Code dar. Aber droht ihnen eine ähnliche Randexistenz wie asyncio?
Der typische Anwendungsfall für asyncio
ist die Webentwicklung. Coroutinen
eignen sich gut für prozessunabhängige Netzwerkaufrufe wie HTTP-Requests und
Datenbankabfragen. Warum sollte der gesamte Python-Interpreter blockiert werden,
während darauf gewartet wird, dass eine Abfrage auf einem anderen Server
ausgeführt wird? Und dennoch unterstützen beliebte Frameworks noch immer nicht
asyncio
:
Django unterstützt nur teilweise
asyncio
; so wird beim ORM „noch an der Unterstützung von async“ gearbeitet.Flask wird wahrscheinlich immer synchron bleiben.
SQLAlchemy hat erst 2023
asyncio
-Unterstützung erhalten, siehe What’s New in SQLAlchemy 1.4?.Im Python für Data Science-Tutorial wird
asyncio
nur als letztes Mittel zur Performance-Optimierung empfohlen.Siehe auch
Dies hat auch mit einigen bekannten Problemen von asyncio
zu tun:
asyncio
unterstützt keine asynchronen Operationen auf dem Dateisystem. Selbst wenn Dateien mitO_NONBLOCK
geöffnet werden, werden Lese- und Schreibvorgänge blockiert. Eine Lösung hierfür besteht darin, das Paketaiofiles
zu verwenden, das euch asynchrone Datei-Funktionen bietet.asyncio
ist nicht intuitiv. Was bedeutet es beispielsweise, wenn Code „blockiert“ wird, und wann ist es notwendig, auf Threads auszuweichen? Ohne diese Grundlagenkenntnisse wird asynchroner Code Fehlverhalten zeigen, aber an sich nicht kaputtgehen. Developer erhalten also nicht das schnelle Feedback, das sie von Python erwarten.„Eine Event Loop läuft in einem Thread (normalerweise dem Haupt-Thread) und führt alle Callbacks und Tasks in diesem Thread aus. Während ein Task in der Event Loop läuft, können keine anderen Tasks im selben Thread ausgeführt werden. Wenn ein Task einen await-Ausdruck ausführt, wird der laufende Task angehalten und die Event Loop führt den nächsten Task aus.“
Quelle: Concurrency and Multithreading
Macht der „Free-Threaded”-Modus asyncio
nützlicher oder überflüssig?¶
Python 3.13 führte eine „Free-Threaded”-Version von Python ein, bei der das GIL entfernt und durch kleinere, granularere Sperren ersetzt wurde. Die 3.13-Version erwies sich jedoch für den produktiven Einsatz nicht stabil genug. In Python 3.14 scheint dies nun besser auszusehen, und wir fragen uns nun, ob wir „Free-Threaded” in einigen gut getesteten Projekten einführen sollten.
Dabei wird jedoch die Unterstützung sowohl synchroner als auch asynchroner
APIs bleibt jedoch eine große Herausforderung. Auch
sollte weiterhin selektiv vorgegangen werden, wo Asynchronität unterstützt
werden soll. So unterstützt ein Großteil der Python-Standardbibliothek
Asynchronität nicht nativ. Auch die Dunder-Methoden und __init__
können
nicht asynchron sein, sodass dort keine asynchronen Netzwerk-Anfragen verwendet
werden können.
Ggf. muss auch das Backend für synchrone und asynchrone Vorgänge fragmentiert werden:
für synchrone HTTP-Aufrufe eignen sich
requests
undhttpx
als Backendsfür asynchrone Vorgänge sind es
aiohttp
undhttpx
Da keines dieser Backends Teil der Python-Standardbibliothek ist, sind die
Einführung und Unterstützung für die wichtigsten CPython-Plattformen nicht
synchronisiert. Beispielsweise verfügt aiohttp
derzeit weder über Python
3.14-Wheels noch über Free-Threaded-Unterstützung.
Das Testen eures asynchronen Codes erfordert verschiedene Mocks, verschiedene Aufrufe und im Fall von pytest eine ganze Reihe von Erweiterungen und Mustern für Fixtures. Dies wird meist sehr verwirrend.
Siehe auch
Anthony Shaw: async test patterns for Pytest
Resümee¶
Die Anwendungsfälle für asyncio
sind weiterhin sehr begrenzt und die
Popularität daher sehr eingeschränkt. Die Popularität des asynchronen
Web-Frameworks FastAPI ist
jedoch weiter gestiegen und verzeichnet derzeit über 100 Millionen Downloads
pro Monat. Wenn wir bedenken, dass asynchrone Prozesse überwiegend für HTTP- und
Netzwerk-Zugriffe verwendet werden, ist dies eher ein Erfolg von uvloop, einer alternativen Implementierung des
Event Loop, die von FastAPI verwendet wird. Ob in Python 3.14 mit der
Unterstützung für Sub-Interpreter und Free-Threading-Funktionen mehr parallele
und gleichzeitige Anwendungsfälle praktisch und nützlich werden, wird sich erst
noch zeigen müssen.