Absicht zur Annahme von PEP 703, das den CPython-GIL optional macht
(discuss.python.org)- Der Python Steering Council beabsichtigt, PEP 703 anzunehmen, wodurch der GIL in CPython optional wird; die Reaktionen der Community auf den no-GIL-Vorschlag und PEP 703 sind insgesamt ebenfalls positiv
- Langfristiges Ziel ist die Vereinheitlichung auf einen no-GIL-Build; eine dauerhafte Aufspaltung in with-GIL- und no-GIL-Builds sowie im Ökosystem der Erweiterungsmodule soll vermieden werden
- Während der Umstellung ist Abwärtskompatibilität die zentrale Einschränkung; auch Drittanbieter-Code, der für no-GIL angepasst wurde, muss weiterhin in with-GIL-Builds funktionieren
- Geplant ist eine dreistufige Umstellung: kurzfristig experimenteller Build, mittelfristig unterstützter Build, langfristig Standard-Build. Der experimentelle Build könnte in Python 3.13 landen, aber eine Verschiebung auf 3.14 würde nicht als Problem gesehen
- Vor der Umstellung des Standard-Builds müssen Community-Unterstützung sowie Erfahrungen mit APIs, Packaging und Distribution geprüft werden; wenn die Verwirrung größer ist als der Nutzen, sollte PEP 703 gestoppt und nach anderen Lösungen gesucht werden
Richtung des Steering Council zur Annahme von PEP 703
- Der Python Steering Council beabsichtigt, PEP 703 anzunehmen
- In der Umfrage zum no-GIL-Vorschlag gab es insgesamt positive Reaktionen, und auch der Steering Council steht sowohl der allgemeinen Idee als auch PEP 703 überwiegend positiv gegenüber
- Allerdings werden die Details der Annahme noch ausgearbeitet und sollen in den kommenden Wochen finalisiert werden
Umstellungsprinzip ohne dauerhafte Aufspaltung
- Langfristig, vermutlich über einen Zeitraum von mehr als 5 Jahren, sollte der no-GIL-Build der einzige Build werden
- Eine dauerhafte Trennung in with-GIL- und no-GIL-Builds ist nicht erwünscht
- Auch im Ökosystem der Erweiterungsmodule soll eine dauerhafte Zweiteilung nach den beiden Builds vermieden werden
- Abwärtskompatibilität muss sehr vorsichtig behandelt werden
- Man möchte keine weitere Python-3-Umstellung schaffen
- Auch wenn Drittanbieter-Code angepasst wird, um no-GIL-Builds zu unterstützen, müssen diese Änderungen weiterhin in with-GIL-Builds funktionieren
- Fragen der Abwärtskompatibilität mit älteren Python-Versionen müssen separat behandelt werden
- Dies ist kein Python 4
- Anforderungen an ABI-Kompatibilität, die Details der beiden Builds und die Auswirkungen auf die Abwärtskompatibilität werden noch geprüft
Bedingungen, die vor der Umstellung des Standards geprüft werden müssen
- Bevor der no-GIL-Build zum Standard gemacht wird, muss geprüft werden, ob ausreichend Community-Unterstützung vorhanden ist
- Man kann nicht einfach nur den Standard ändern und die Community dann selbst herausfinden lassen, welche Arbeiten nötig sind
- Core-Entwickler müssen den neuen Build-Modus und die zugehörigen Komponenten selbst praktisch erproben
- Beim Aufräumen der Thread-Sicherheit bestehenden Codes könnten neue C API und Python API nötig werden
- Die dabei gewonnenen Erkenntnisse sollten mit der Python-Community geteilt werden
- Es muss geprüft werden, ob die Änderungen, die Core-Entwickler wünschen, und die Änderungen, die von der Community verlangt würden, auf einem akzeptablen Niveau liegen
- Bis no-GIL zum Standard gemacht wird, muss es möglich sein, die Richtung zu ändern, wenn sich zeigt, dass die Änderungen zu viel Verwirrung stiften und der Nutzen gering ist
- In diesem Fall muss auch die Entscheidung möglich sein, sämtliche Arbeiten zurückzudrehen
- Daher sollte no-GIL-spezifischer Code in gewissem Maß identifizierbar sein
Dreistufiger Umstellungsplan
- Kurzfristig wird der no-GIL-Build als experimenteller Build-Modus hinzugefügt
- Er könnte vermutlich in Python 3.13 aufgenommen werden
- Eine Verschiebung auf Python 3.14 wird nicht als Problem gesehen
- Der experimentelle Status soll klarstellen, dass Core-Entwickler diesen Build-Modus unterstützen, aber nicht erwartet werden kann, dass die Community ihn sofort unterstützt
- Um Community-Unterstützung bei API-Design, Packaging und Distribution zu ermöglichen, ist Zeit nötig
- Distributionen wird nicht empfohlen, einen experimentellen no-GIL-Build als Standard-Interpreter bereitzustellen
- Mittelfristig wird der no-GIL-Build zu einem unterstützten Ziel gemacht, aber noch nicht zum Standard
- Es braucht die Überzeugung, dass die Community-Unterstützung für den Produktionseinsatz ausreichend ist
- In dieser Phase wird ein Zieltermin oder eine Python-Version festgelegt, zu dem bzw. mit der no-GIL zum Standard gemacht werden soll
- Der Zeitpunkt hängt stark von der Abwärtskompatibilität von API-Änderungen, dem Umgang mit der stable ABI und dem Arbeitsaufwand ab, den die Community für nötig hält
- Es kann mindestens 1 bis 2 Jahre dauern, oder länger
- Sobald no-GIL als unterstützt deklariert ist, könnten einige Distributoren beginnen, no-GIL standardmäßig anzubieten; das kann jedoch davon abhängen, wie viele Python-Pakete zu diesem Zeitpunkt no-GIL unterstützen
- Langfristig soll no-GIL zum Standard gemacht und Spuren des GIL entfernt werden
- Abwärtskompatibilität soll nicht unnötig gebrochen werden
- Zwei gängige Build-Modi lange beizubehalten, kann die Belastung für die Community erhöhen, etwa weil sich Testressourcen und Debugging-Szenarien verdoppeln
- Trotzdem kann man nichts überstürzen, und bis zu dieser Phase können bis zu 5 Jahre vergehen
Kontinuierliche Neubewertung und Möglichkeit zum Abbruch
- Während des gesamten Prozesses müssen nicht nur der Steering Council, sondern auch die Core-Entwickler den Fortschritt und den vorgeschlagenen Zeitplan kontinuierlich neu bewerten
- Man möchte nicht, dass diese Arbeit zu einem weiteren 10 Jahre dauernden Kampf um Abwärtskompatibilität wird
- Wenn sich Anzeichen zeigen, dass PEP 703 problematisch wird, muss es möglich sein, abzubrechen und nach anderen Lösungen zu suchen
- Es muss regelmäßig geprüft werden, ob die fortlaufende Arbeit ihren Aufwand wert ist
1 Kommentare
Meinungen auf Hacker News
Über Jahrzehnte hinweg waren viele C-Bibliotheken in ihren Handbüchern mit Warnungen versehen, dass sie in asynchronen, reentranten und rekursiven Kontexten instabil seien.
Trotzdem haben wir gelernt, damit umzugehen, und reentranzsichere Versionen wurden nach und nach ausgeliefert, ohne die API-Instabilität stark zu erhöhen.
Es gab Dinge wie String-Parsing, das direkt im vorhandenen Speicher tokenisierte, DNS-Aufrufe mit statischen Puffern oder Code, der sich auf Vax-spezifisches Stack-Verhalten verließ; den GIL sehe ich dabei als Segen und Fluch zugleich.
Dadurch habe ich mir wohl angewöhnt, selbst bei APIs, die ich einigermaßen kenne, die Dokumentation zu prüfen, falls ich wichtige Details übersehen habe oder sich etwas geändert hat.
Als ich damals plattformübergreifendes C++ machte, sah ich zum ersten Mal Java; es brachte Nebenläufigkeit, Garbage Collection und viele Funktionen, die einfacher zu nutzen waren als in C++, von Anfang an mit, und ich war überzeugt, dass es groß werden würde.
Später begannen Mainstream-Entwickler, Python zu verwenden; soweit ich mich erinnere, war es ursprünglich als einbettbare Erweiterungssprache gedacht und deshalb einfach, wodurch auch der GIL mehr Sinn ergab.
Es ist nicht so, dass jemand einen Schalter umlegt und auf einen Schlag Unmengen fragwürdigen C-Codes kaputtmacht.
Inzwischen gibt es 128-Core-CPUs, und selbst günstige CPUs haben 6 Kerne; die Einschränkung, an Single-Core-Performance gebunden zu sein, wird mit der Zeit immer größer.
Anfangs glaubte ich, das seien Probleme, die sich in ein paar Wochen, höchstens Monaten lösen ließen; ich wusste einfach viel zu wenig.
In C ist die Interaktion mit nicht threadsicheren Funktionen viel direkter, und wenn man C schreibt, ist man meistens vorsichtiger.
In Python gibt es ganze C-Module mit globalem Zustand; wenn man etwa 10 davon lädt und dann noch die Komplexität des Interpreters dazunimmt, weiß bald niemand mehr, was eigentlich passiert.
Schon heute prüfen die meisten Entwickler, selbst Core-Entwickler, nicht auf Memory Leaks; ich glaube nicht, dass sie tsan laufen lassen, und selbst wenn, dann vermutlich nur mit kleinen Testsammlungen, die vielleicht 10 % des Codes abdecken.
Wenn ich mir die Praktiken der Softwareentwicklung in Python ansehe, besonders im AI-Bereich, bin ich gegenüber diesem Feature sehr pessimistisch.
Interessant ist es schon.
Python besteht größtenteils aus gemeinsam genutzten C-Bibliotheken, die in dem Wissen geschrieben wurden, dass sie sich auf einen globalen Lock verlassen können.
Manche davon sind einfach genug, um auch ohne Lock gut zu laufen, andere brauchen weiterhin Locks und werden nun unter Druck geraten, ohne GIL ausgeführt zu werden.
Einige davon werden in ihrem eigenen Bereich selbst Locks implementieren; vielleicht war ja genau das, was Python wirklich gefehlt hat, ein Haufen provisorischer Mutex-Aufrufe, verstreut über das ganze Ökosystem.
Ich hätte nicht erwartet, dass Python dadurch kaputtgeht, dass unter dem Vorwand der Performance Data Races und Deadlocks eingeführt werden.
C-Bibliotheken, die unter der Annahme eines globalen Locks geschrieben wurden, threadsicher zu machen, ist eine Art Arbeit, von der selbst Nebenläufigkeitsexperten abraten und bei der man sich bei der Implementierung leicht vertut.
Meine Hypothese ist, dass die meisten, die Python-C-Erweiterungen geschrieben haben, keine Nebenläufigkeitsexperten sind, sondern gute Programmierer, die Herausforderungen nicht aus dem Weg gehen; mit dieser Kombination wirken Data Races/Hänger/Segfaults fast unvermeidlich.
Aber die Erwartung, es in 5 Jahren auf Opt-in umzustellen, ist zu optimistisch.
Alle Bibliotheksentwickler müssten ihre eigenen Bibliotheken und sogar Python-Bibliotheken anpassen; das ist harte Arbeit, und selbst wenn sie gut gemacht ist, merkt es niemand und sie wird kaum belohnt.
Viele Bibliotheken hatten nie einen Anwendungsfall für Multiprocessing, und bei großen Bibliotheken sind subtile Bugs unvermeidlich; nicht reproduzierbare Beschwerden und aufgebende Entwickler wirken wie ein garantiertes Ergebnis.
Auch Python mit GIL unterstützt Threads, also sollten solche Bibliotheken zumindest reentranzsicher sein.
Wenn eine Bibliothek zwar reentrant, aber nicht threadsicher ist, könnte es reichen, einen einzigen globalen Lock um alle Aufrufe zu legen; das ist dem, was der GIL getan hat, ziemlich ähnlich.
Bestehende Bibliotheken ohne GIL lauffähig zu machen, dürfte in vielen Fällen relativ geradlinig sein, auch wenn Parallelität dabei geopfert werden kann.
Das Kernproblem dürften Bibliotheken sein, die von der C-Seite aus in die Python-Runtime zurückrufen.
Eine naive Frage, aber wozu braucht jemand No-GIL, wenn es die Pakete asyncio und multiprocessing gibt?
Ich hatte in Python wegen des GIL nie Probleme und habe es immer umgangen, indem ich einen ThreadPool oder ProcessPool gestartet oder bei Bedarf eine asynchrone Bibliothek verwendet habe.
Ich frage mich, ob es No-GIL-Anwendungsfälle gibt, die sich nicht mit multiprocessing lösen lassen.
Ich dachte, Single-Thread-Ausführung ohne den Overhead von Concurrency-Primitiven sei am besten für High-Performance Computing. Wie der LMAX Disruptor gezeigt hat.
asyncio ist im Wesentlichen Single-Threaded und damit Single-Core; multiprocessing ist Multi-Core und daher für die Performance besser, aber jeder Prozess ist relativ schwergewichtig und es kommt Overhead für Shared Memory hinzu.
GIL-basiertes Multithreading ist Single-Core und außerdem schwer korrekt zu verwenden.
No-GIL-Multithreading ist Multi-Core, aber schwer zu verwenden; zur Implementierung weiß ich es nicht genau, aber Shared Memory sollte schneller sein als bei multiprocessing.
Wenn man ein neues System entwirft, stimme ich zu, dass man für fast alle Python-Anwendungsfälle die Finger von Threads lassen und asyncio/multiprocessing nutzen sollte.
Python-Programme, die schnelles Multithreading brauchen, hätten oft von Anfang an nicht in Python geschrieben werden sollen, aber da es nun einmal Leute gibt, die CPU-intensive Codes bereits in Python geschrieben haben, ist No-GIL praktisch nützlich.
Man nehme einen Webserver, der mit gemeinsamem Zustand mehreren Clients gleichzeitig antwortet; multiprocessing nutzt pickle zum Hin- und Herschieben von Daten, was erheblichen Performance-Overhead verursacht.
Wenn man zum Beispiel eine 1-GB-Datenstruktur im Speicher halten und parallel darauf rechnen möchte, ist das mit multiprocessing nur schwer performant umzusetzen.
Mit pickle lassen sich nicht alle Objekte teilen, und Fehler wegen nicht pickelbarer Objekte sind bei komplexen Datenstrukturen sehr schwer zu debuggen.
Insbesondere Objekte, die von nativen Bibliotheken erzeugt wurden, lassen sich möglicherweise nicht teilen.
Auch Verarbeitungen, die zur Laufzeit Zustand teilen müssen, sind mit dem multiprocessing-Modul sehr schwierig; sogar der Prometheus-Exporter für Flask braucht einen seltsamen Hack mit einem temporären Verzeichnis, um Statistiken aus allen Prozessen zusammenzuführen.
Bei vielen Anwendungen von DeepMind möchte man pro Prozess etwa 50 bis 100 Threads laufen lassen, aber oft wird der GIL schon bei weniger als 10 Threads zum Engpass.
Als Workaround werden zwar auch Subprozesse verwendet, doch in vielen Fällen wird der Overhead der Interprozesskommunikation zu groß, sodass am Ende große Teile der Python-Codebasis nach C++ verschoben werden.
Für durchschnittliche Nutzung wie Web-Apps mag multiprocessing ausreichen, aber bei großen AI-Workloads wie bei Google und DeepMind schränkt der GIL die Nutzung von Python tatsächlich ein.
Das ist auch der Grund, warum Meta drei Ingenieurjahre in diese Arbeit investieren will: https://news.ycombinator.com/item?id=36643670
Wie der Name schon sagt, hilft es wirklich nur bei I/O-bound Problemen.
Daten über mehrere Prozesse hinweg zu teilen, ist enorm schmerzhaft, und Datenkontrolle zusammen mit Prozess-Orchestrierung zu betreiben, ist noch schmerzhafter.
Prozesse sind teuer, und wegen der genannten Schwierigkeiten beim Teilen von Daten ist auch greenlet keine echte Alternative.
Aber in Bereichen wie AI und Data Science, in denen Python eine große Rolle spielt, ist es ein großer Vorteil, viele CPU/GPU-bound Threads starten und laufen lassen zu können.
Viele C-Erweiterungen wurden nicht mit Multithreading im Hinterkopf geschrieben, daher können Probleme entstehen, und ich vermute, dass das auch tatsächlich passieren wird.
Ein kleines unsicheres Beispiel, falls auf
lstvon einem anderen Thread aus zugegriffen werden kann, gibt es hier: https://news.ycombinator.com/item?id=36649769Schon heute kann C-Code über eine
__del__-Methode in Python-Bytecode zurückrufen, und wenn dieser Bytecode lang genug ist, vermutlich etwa 100 Instruktionen, kann ein Context Switch stattfinden.Das ist allerdings ein extrem seltener Fall, und viel C-Erweiterungscode wurde nicht unter Berücksichtigung solcher Situationen geschrieben.
Nutzer von C-Erweiterungen verlassen sich möglicherweise darauf, dass diese atomar ausgeführt werden.
Zum Beispiel funktioniert es derzeit gut, numpy-Arrays in einen Thread-Pool hineinzugeben und wieder herauszubekommen, aber ohne GIL könnte das kaputtgehen.
Deshalb gehen der Vorschlag und die Arbeitsrichtung dahin, den non-GIL-Modus vollständig optional zu halten und nicht zum Standard zu machen.
Die mutigen wenigen, die ihn aktivieren und nutzen, müssen bereit sein, enorm viel Zeit darauf zu verwenden, subtile Race Conditions in jahrzehntealtem Python-Bibliothekscode zu finden und zu beheben.
Frühe Anwender werden viel Schmerz erleiden oder, wahrscheinlicher, non-GIL nur auf sehr spezialisierte dedizierte Prozesse beschränken, bei denen die Abhängigkeiten so weit wie möglich reduziert sind.
Man geht von einem Zustand, in dem man vermutet, dass es Probleme gibt, zu einem Zustand über, in dem man genau weiß, wo die Probleme liegen, und den Rest kann man dann Stück für Stück von der Liste abarbeiten.
Man kann irgendeine Form von Mutex um den Code herum hinzufügen oder auf eine alternative Implementierung wechseln, die kein nativer Code ist und weniger Probleme verursacht.
Das Gegenargument scheint vor allem zu sein, dass es viel Arbeit ist, nicht dass es unmöglich wäre.
Wenn genügend Leute daran arbeiten, kann dabei ein Ergebnis herauskommen.
Sonst hätten sie statt eines schrittweisen Ansatzes, bei dem Nutzer sich ausdrücklich für den No-GIL-Modus entscheiden, einen Plan angekündigt, den GIL plötzlich komplett zu entfernen.
Man kann sich an den Übergang von Text zu Unicode, von 32 Bit zu 64 Bit, von Intel zu ARM und an Y2K erinnern.
No-GIL ist eine deutlich kleinere Änderung und kann demselben Migrationspfad folgen, ohne radikal etwas kaputtzumachen.
Selbst wenn etwas kaputtgeht, wird es gut definierte Wege geben, mit solchen Fällen umzugehen.
Wir haben diese Übergänge schließlich überlebt, und es ist erfreulich zu sehen, dass es vorangeht.
Es wird weitere Bereiche öffnen, die bisher als unmöglich markiert waren.
Eines der Dinge, die frühes Swift gut gemacht hat, war, Breaking Changes in ein Versprechen einzubetten, und alle wussten, woran sie waren, und haben sich gut angepasst.
Manchmal wünsche ich mir, Python würde denselben Weg gehen.
Von 32 Bit zu 64 Bit, zu ARM und bei Y2K konnte man testen, ob es funktioniert.
Natürlich können Tests Fehlerfälle übersehen, aber die ausgeführten Tests sind deterministisch.
Hier dagegen lautet die Antwort, egal wie viel man testet: „Es ist korrekt, oder wir haben die richtige Race Condition noch nicht getroffen.“
Zwar wird ausdrücklich gesagt, dass man das Python-3-Übergangsszenario nicht wiederholen will, aber der aktuelle Ansatz wirkt erschreckend nah daran.
Viel hängt von der Python-Community und den Distributionskanälen ab.
Die Community könnte es nicht rechtzeitig übernehmen, oder Distributionen wie Ubuntu, Fedora und Anaconda könnten vorschnell vorpreschen.
Es ist noch zu früh für ein Urteil, aber ich frage mich, wie viel Kontrolle der Steering Council tatsächlich hat, um solche Szenarien zu vermeiden.
Fünf Jahre sind zu lang dafür, dass Python zwei Modi hat.
Ein halbes Jahrzehnt reicht, damit sich beide Modi als Status quo verfestigen, und auch danach werden alte Stack-Overflow-Beiträge weiter existieren.
Ich bin nicht optimistisch, dass aus fünf Jahren nicht zehn Jahre Unsicherheit und Bruch werden.
Umgekehrt könnten fünf Jahre zu kurz sein, um sämtlichen C-Code hervorzuziehen, zu reparieren, zu testen und als ausgereift zu bezeichnen.
Unternehmen, die Unterstützung zugesagt haben, könnten einige Projekte mechanisch konvertieren und die eigentlichen Entwickler nerven oder mit Forks drohen.
Die Bugs werden dann über Jahre hinweg von echten unbezahlten Entwicklern ausgebügelt.
Aber Python braucht irgendeinen „Erfolg“, und das ist eine gute PR-Zeile.
In der Python-Welt scheint Korrektheit nicht besonders wichtig zu sein.
Wegen dieser Geschichte klingt es so, als wolle man lieber zwei Ausführungsmodi innerhalb von CPython 3 beibehalten, statt auf einen weiteren großen Major-Übergang zuzusteuern.
Es ist gut, dass man sich sehr bewusst ist, dass daraus leicht eine Python-4-Katastrophe werden könnte.
Man muss extrem vorsichtig sein, damit das yes-GIL-Verhalten nicht versehentlich beeinflusst wird.
Wenn irgendeine Form eines emulierten GIL nicht exakt dem echten GIL entspricht, sind alle möglichen seltsamen Fälle denkbar.
Erstens: Man will nicht, dass es so läuft.
Zweitens: Wenn es so läuft, gibt man schnell auf.
Beides ist wichtig, aber das entscheidende dritte Stück „und so werden wir das erreichen“ scheint zu fehlen.
Es wird bereits gesagt, dass GIL und No-GIL fünf Jahre oder länger koexistieren könnten.
Für Tool-Entwickler bedeutet das, dass sich die Kosten mindestens für die nächsten fünf Jahre verdoppeln.
Denn Menschen werden Tools in beiden Modi nutzen wollen, ob produktiv oder experimentell.
GIL steht für Global Interpreter Lock.
Eine gute Erklärung gibt es hier: https://realpython.com/python-gil/
Hier gibt es zwei große Probleme.
Erstens sind manche Verbesserungen es wert, die Abwärtskompatibilität zu brechen, und die Entfernung des GIL ist eine solche Verbesserung.
Ob die Änderungen in Python 3 das wert waren, ist umstritten, und dass
printzu einer Funktion wurde, wirkt nicht besonders wertvoll.Allerdings wurde der Übergang von 2 zu 3 von einer lautstarken Minderheit teils übertrieben dargestellt, und nach meiner Erfahrung mit der Migration von mehr als fünf Codebasen von 2 auf 3 hatten die meisten nur wenige Probleme.
Das größte Problem waren Codebasen, in denen frühere Entwickler für alles eine Bibliothek hereingezogen hatten und die dadurch zu einem Haufen verwaister Bibliotheken wurden; solcher Code bekommt auch dann Probleme, wenn die Kernsprache die Kompatibilität nicht bricht.
Die Antwort ist nicht, die Sprache dazu zu drängen, niemals wieder Kompatibilität zu brechen, sondern nicht zu erwarten, dass es eine nachhaltige Strategie ist, praktisch ganz pip mitzunehmen.
Derzeit bekommt der Steering Council von einer lautstarken Minderheit so viel Kritik ab, dass er Breaking Changes fürchtet.
Aber die Entfernung des GIL betrifft einen so fundamentalen Teil der Funktionsweise von Python, dass sie ein Breaking Change sein muss; es wäre besser, das anzuerkennen und einen Migrationsplan aufzustellen, statt aus Angst vor den Nutzern die Fakten nicht anzuerkennen und das Unmögliche zu versuchen, nämlich es nicht brechend zu machen.
Auch in Python 3.11 ist meine Codebasis kaputtgegangen, und die Korrektur war nicht schwierig, aber ich hätte mir eine bessere Kommunikation gewünscht, dass so etwas passieren kann.
Zweitens ist das grundlegendere Problem, dass viele andere Funktionen von Python rund um den GIL entstanden sind.
Insbesondere das asynchrone Paradigma ergibt wegen des GIL viel Sinn; ohne GIL wäre rückblickend ein Erlang-artiges send/recv-Actor-Modell eine deutlich bessere Richtung gewesen.
Das lässt sich nur schwer zurückdrehen, und es wirkt, als werde Python in eine weniger kohärente Sammlung von Funktionen gedrängt, die nicht gut zusammenpassen — zu wenig, zu spät.
Dank an die Python-Kernentwickler und den Steering Council; Python gehört neben Java und C zu meinen Lieblingssprachen.
Ich begrüße echtes Multithreading in Python sehr.
Je nach Projekt nutze ich sowohl multiprocessing als auch multithreading; ein Beispiel für multiprocessing findet sich unter [0], und ein Beispiel, bei dem Python Threads für I/O-lastige Aufgaben verwendet werden, unter [1].
Allerdings wäre es deutlich effizienter, echte Threads zu verwenden.
Threads können beliebige Datenmengen in einer einzigen atomaren und nahezu sofortigen Operation austauschen; über das lokale Loopback-Interface, multiprocessing oder Pipes ist das nicht möglich.
Ich arbeite an einer Multithreading-Architektur, die ich „three tier multithreading architecture“ nenne.
https://github.com/samsquire/three-tier-multithreaded-archit...
Ziel ist ein extrem skalierbarer und performanter Server, aber Python ist dafür vermutlich nicht das passende Werkzeug.
[0]: https://news.ycombinator.com/item?id=36897054 Erläuterung zur Verwendung von multiprocessing
[1]: https://devops-pipeline.com/ Beispiel für die Verwendung von multithreading