Solange die meisten von uns Python schreiben, prägt eine Tatsache, wie wir nebenläufige Programme bauen: der Global Interpreter Lock. Der GIL ist der Grund, warum CPU-gebundene Python-Threads nie echte Parallelität boten, warum „nimm einfach multiprocessing“ zum Reflex wurde und warum „Python ist langsam bei paralleler Arbeit“ zur Binsenweisheit geriet. Free-threaded Python ändert die Voraussetzung. Dieser Leitfaden erklärt, was der GIL eigentlich ist, was seine Entfernung bringt: und was nicht, wo sie hilft, wo sie schadet und wie man über ihren Einsatz nachdenkt, ohne dem Hype in die eine oder andere Richtung zu verfallen.
Was Sie tatsächlich verstehen werden
- Was der GIL ist und warum er so lange existierte
- Was „free-threaded“ Python ändert: und was nicht
- Die ehrlichen Kompromisse: Kosten für Single-Thread und C-Erweiterungskompatibilität
- Wann Free Threading ein echter Gewinn ist, verglichen mit Async oder Multiprocessing
- Ein pragmatischer Weg, es für Ihre eigenen Workloads zu bewerten
Info
Die kurze Antwort
Der GIL verschwindet: als offiziell unterstützter optionaler Build, nicht als stillschweigender Standard für alle über Nacht. Free-threaded Python ist real und wird unterstützt, aber es ist eine bewusste Entscheidung mit Kompromissen, kein kostenloser Geschwindigkeitsschub, den Sie pauschal einschalten.
Was der GIL eigentlich ist
Der Global Interpreter Lock ist eine einzelne Sperre innerhalb von CPython, die sicherstellt, dass immer nur ein Thread Python-Bytecode ausführt. Er existiert, weil er den Interpreter für Single-Thread-Code einfacher und schneller machte und die Speicherverwaltung (Reference Counting) sicher hielt, ohne überall Sperren zu verteilen. Der Preis: Threads können Python-Code nicht wirklich parallel ausführen. Zwei Threads, die schwere Berechnungen durchführen, wechseln sich ab, anstatt nebeneinander zu laufen, sodass Sie von Threads Nebenläufigkeit, aber keine Parallelität bekommen.
With the GIL (CPU-bound work, 4 threads, 4 cores):
Thread 1 ▓░░░▓░░░▓░░░ ← only one runs Python at a time
Thread 2 ░▓░░░▓░░░▓░░ they take turns; 3 cores sit idle
Thread 3 ░░▓░░░▓░░░▓
Thread 4 ░░░▓░░░▓░░░
Free-threaded (no GIL):
Thread 1 ▓▓▓▓▓▓▓▓▓▓▓▓ ← all four run in parallel
Thread 2 ▓▓▓▓▓▓▓▓▓▓▓▓
Thread 3 ▓▓▓▓▓▓▓▓▓▓▓▓ real use of all cores
Thread 4 ▓▓▓▓▓▓▓▓▓▓▓▓
Was Free Threading ändert
In einem free-threaded Build wird der GIL entfernt, sodass mehrere Threads gleichzeitig Python-Bytecode auf mehreren Kernen ausführen können. Für CPU-gebundene Arbeit, die Sie auf Threads aufteilen können, ist dies die lang ersehnte Befreiung: echte Shared-Memory-Parallelität ohne den Overhead und die Umständlichkeit, separate Prozesse zu starten und Daten zwischen ihnen zu serialisieren. Ein Prozess, gemeinsame Objekte, alle Ihre Kerne.
Stellen Sie sich eine peinlich parallele CPU-Aufgabe vor. Im Standard-Build bringt Ihnen Threading fast nichts: der GIL serialisiert die Arbeit. Derselbe Code im free-threaded Build skaliert über Kerne:
import sys
from concurrent.futures import ThreadPoolExecutor
def crunch(n: int) -> int: # pure CPU work — no I/O to hide behind
total = 0
for i in range(n):
total += i * i
return total
def run() -> None:
with ThreadPoolExecutor(max_workers=8) as pool:
list(pool.map(crunch, [20_000_000] * 8))
# Tell which world you're in at runtime:
print("GIL enabled:", sys._is_gil_enabled()) # True on standard build, False on 3.14t
run()
# Standard build: threads take turns — wall time ~= running all 8 tasks serially.
python3.14 bench.py # GIL enabled: True
# Free-threaded build: threads run in parallel — wall time ~= one task (on 8 cores).
python3.14t bench.py # GIL enabled: False ← the 't' build is the no-GIL one
PYTHON_GIL=0 python3.14t bench.py # force the GIL off if an extension re-enabled it
Was es NICHT ändert
Free Threading ist kein magischer „mach Python schnell“-Knopf, und mehrere verbreitete Hoffnungen sind fehl am Platz.
✓ Vorteile
- Echte Parallelität für CPU-gebundene, thread-parallele Workloads
- Gemeinsamer Speicher: kein Pickling von Daten zwischen Prozessen
- Geringerer Overhead als Multiprocessing für Many-Core-Berechnungen
✕ Nachteile
- I/O-gebundener Code skalierte bereits gut mit Threads/Async: wenig Gewinn dort
- Single-Thread-Programme können etwas langsamer laufen, nicht schneller
- Es macht sequenziellen Code nicht schneller; nur parallelisierbare Arbeit profitiert
- Es führt klassische Data Races wieder ein: gemeinsamer Zustand braucht jetzt echte Sorgfalt
Warnung
Kein GIL bedeutet, dass Sie wieder für Thread-Sicherheit verantwortlich sind
Der GIL schützte versehentlich viel schlampigen Code mit gemeinsamem Zustand. Ohne ihn laufen zwei Threads, die dasselbe Objekt verändern, wirklich gleichzeitig, sodass Race Conditions, die zuvor maskiert waren, auftauchen können. Free-threaded Code benötigt dieselbe Sperrdisziplin wie jede andere echt parallele Sprache. Das ist ein Feature mit Verantwortlichkeiten.
Hier ist die Art von Fehler, die der GIL früher versteckte. Zwei Threads, die einen gemeinsamen Zähler erhöhen, führen ein Read-Modify-Write durch, das sich überlappen kann, sodass Inkremente verloren gehen: und die Lösung ist dieselbe wie in jeder parallelen Sprache: Schützen Sie gemeinsamen veränderlichen Zustand mit einer Sperre.
import threading
# ❌ Racy without the GIL: counter += 1 is read, add, write — and can interleave.
counter = 0
def unsafe():
global counter
for _ in range(1_000_000):
counter += 1 # two threads can both read the same value → lost updates
# ✅ Correct: a lock makes the update atomic.
counter = 0
lock = threading.Lock()
def safe():
global counter
for _ in range(1_000_000):
with lock:
counter += 1 # only one thread mutates at a time
# Better still: avoid shared mutable state. Have each thread return its own
# partial result and combine them at the end — no lock, no contention.
Die zwei ehrlichen Kosten
1. Single-Thread-Overhead
Die Entfernung des GIL erfordert Änderungen an der Speicherverwaltung, die Single-Thread-Code etwas langsamer machen können als im Standard-Build. Wenn Ihr Programm überwiegend sequenziell ist, kann der free-threaded Build Sie Performance kosten, anstatt sie zu sparen. Die ganze Wette zahlt sich nur aus, wenn Sie CPU-Arbeit wirklich über Threads parallelisieren.
2. Kompatibilität mit C-Erweiterungen
Ein großer Teil des Werts von Python steckt in C-Erweiterungen: der wissenschaftliche Stack, Datenbanktreiber, Parser. Viele setzen die Existenz des GIL voraus und benötigen Aktualisierungen, um ohne ihn sicher und korrekt zu sein. Das Ökosystem migriert aktiv, aber Sie können nicht davon ausgehen, dass eine beliebige Erweiterung bereit für Free Threading ist. Diese Kompatibilitätskurve bestimmt mehr als alles andere, wie schnell die GIL-freie Welt für alltägliche Anwendungen praktikabel wird.
Das richtige Nebenläufigkeitswerkzeug wählen
Free Threading ersetzt nicht die anderen Werkzeuge: es füllt eine spezifische Lücke. Passen Sie das Werkzeug dem Engpass an.
I/O-gebunden (Netzwerk, Festplatte, DB-Aufrufe)?
Verwenden Sie Async oder normale Threads. Der GIL war hier nie Ihr Problem; Sie warten, nicht rechnen. Free Threading bringt wenig.
CPU-gebunden und parallelisierbar?
Das ist das Heimatrevier von Free Threading: und zuvor von Multiprocessing. Free Threading kann es mit gemeinsamem Speicher und weniger Overhead, sobald Ihre Erweiterungen es unterstützen.
CPU-lastig, aber Erweiterungen noch nicht bereit?
Bleiben Sie vorerst bei Multiprocessing. Die Prozessisolierung umgeht den GIL auf herkömmliche Weise und bleibt eine völlig valide Lösung.
Überwiegend single-threaded?
Bleiben Sie beim Standard-Build. Der freithreaded-Build würde Ihnen wahrscheinlich Single-Thread-Leistung kosten, ohne parallelen Nutzen zu bringen.
alle Ihre Kerne: das Versprechen von freithreaded Python für parallele CPU-Arbeit
Wie Sie es realistisch bewerten
Übernehmen Sie Free Threading nicht blind oder aus Angst. Messen Sie. Richten Sie den freithreaded-Build in einer Testumgebung ein, führen Sie Ihre tatsächliche CPU-lastige Arbeitslast aus und vergleichen Sie die Wanduhrzeit und Korrektheit sowohl mit dem Standard-Build als auch mit Ihrem aktuellen Multiprocessing-Ansatz. Entscheidend ist, dass Sie vor einem Produktionseinsatz sicherstellen, dass jede von Ihnen verwendete C-Erweiterung mit Free Threading kompatibel ist.
Profitipp
Fügen Sie den freithreaded-Interpreter als paralleles CI-Ziel hinzu. Wenn Sie Ihre Suite unter beiden Builds ausführen, werden Erweiterungsinkompatibilitäten und neu aufgedeckte Race Conditions automatisch sichtbar, sodass aus der beängstigenden Frage „Ist unser Code no-GIL-sicher?“ eine grüne oder rote Prüfung wird.
Verschwindet der GIL also endgültig?
Ja: aber verstehen Sie die Tragweite. Der GIL ist in einem offiziell unterstützten Build verschwunden, was einen echten historischen Wandel und die Grundlage für Pythons parallele Zukunft darstellt. In 3.14 ist dies jedoch nicht die Standardeinstellung, die jeder stillschweigend erbt, denn die Single-Thread-Kosten und die Migration der C-Erweiterungen machen dies verfrüht. Die ehrliche Einordnung: Die Ära, in der „Python keine echte Parallelität kann“, geht allmählich zu Ende, und das Tempo wird eher vom Aufholen des Ökosystems als von der Sprache selbst bestimmt.
! Häufige Fehler, die Sie vermeiden sollten
-
✕Erwarten, dass der freithreaded-Build I/O-lastigen Code beschleunigt.
✓Dort war der GIL nie der Engpass: verwenden Sie async oder Threads; Free Threading hilft bei CPU-lastiger Arbeit.
-
✕Annehmen, dass bestehender threaded Code ohne den GIL automatisch sicher ist.
✓Race Conditions, die der GIL maskiert hat, können jetzt auftreten: schützen Sie gemeinsam genutzte veränderliche Zustände mit Sperren.
-
✕Es blindlings ohne Messung übernehmen.
✓Führen Sie Benchmarks Ihrer tatsächlichen Arbeitslast gegen den Standard-Build und Multiprocessing durch, bevor Sie sich festlegen.
-
✕Ignorieren der C-Erweiterungskompatibilität.
✓Überprüfen Sie, ob jede native Abhängigkeit Free Threading unterstützt; viele setzen noch den GIL voraus.
? Häufig gestellte Fragen
Was ist der GIL in einfachen Worten? +
Eine einzelne Sperre innerhalb von CPython, die es nur einem Thread erlaubt, gleichzeitig Python-Bytecode auszuführen. Sie vereinfachte den Interpreter und die Speicherverwaltung, verhinderte aber, dass Threads Python-Code wirklich parallel ausführen.
Macht das Entfernen des GIL Python schneller? +
Nur für CPU-lastige Arbeit, die Sie auf Threads aufteilen können. Single-Threaded-Code kann auf dem freithreaded-Build sogar etwas langsamer laufen, es ist also keine pauschale Beschleunigung.
Sollte ich jetzt Threads, async oder Multiprocessing verwenden? +
Async/Threads für I/O-lastige Arbeit, Free Threading für parallele CPU-Arbeit (sobald Erweiterungen es unterstützen), Multiprocessing, wenn Ihre Erweiterungen noch nicht bereit sind, und den Standard-Build für überwiegend single-threaded Anwendungen.
Ist freithreaded Python produktionsreif? +
Es wird offiziell unterstützt, aber die Einführung wird durch die C-Erweiterungskompatibilität und die Single-Thread-Kosten begrenzt. Bewerten Sie es gezielt für parallele Arbeitslasten, anstatt es überall zu aktivieren.
Wie erkenne ich, welchen Build ich ausführe? +
Prüfen Sie sys._is_gil_enabled() zur Laufzeit oder führen Sie den no-GIL-Interpreter aus (z. B. python3.14t). Der freithreaded-Build meldet den GIL als deaktiviert.
Erfolg
Ein Fundament, keine Ziellinie
Freithreaded Python öffnet eine Tür, die dreißig Jahre lang verriegelt war. Gehen Sie bewusst hindurch: messen Sie Ihre Arbeitslast, überprüfen Sie Ihre Abhängigkeiten und respektieren Sie die Thread-Sicherheit: und Sie erhalten echte Multi-Core-Parallelität in reinem Python. Das ist es wert, richtig gemacht zu werden, statt überstürzt.
Üben Sie unterwegs
Lernen Sie Python, die kostenlose Android-App
Jedes Thema dieser Serie gibt es auch in der App: mundgerechte Lektionen, ausführbare Beispiele, Quizze, Miniprojekte und einen Offline-Python-Spielplatz, der auf Ihrem Handy läuft.
Kommentare
0Noch keine Kommentare. Teile als Erste oder Erster deine Gedanken.