In Python bietet die Standardbibliothek das Modul threading für Multithreading. Threads ermöglichen es, mehrere Operationen parallel innerhalb eines Prozesses auszuführen. In der Standardimplementierung von Python (CPython) gibt es jedoch einen Mechanismus namens GIL (Global Interpreter Lock) – eine globale Sperre des Interpreters, die nur einem Thread erlaubt, den Python-Bytecode gleichzeitig auszuführen.
Das bedeutet, dass in CPython Multithreading keinen echten Parallelismus bei der Ausführung von Python-Code auf Prozessor-Ebene ermöglicht; Parallelität ist nur für Aufgaben nützlich, die mit Wartezeiten verbunden sind (I/O-bound). Für CPU-bound Aufgaben wird empfohlen, das Modul multiprocessing zu verwenden, das mehrere Prozesse startet und GIL umgeht.
Beispiel:
import threading def worker(): print('Start') # schwere Berechnungen print('Ende') threads = [threading.Thread(target=worker) for _ in range(5)] for t in threads: t.start() for t in threads: t.join()
Für Parallelismus bei rechenintensiven Aufgaben verwenden Sie multiprocessing:
from multiprocessing import Pool def square(x): return x*x with Pool(4) as p: print(p.map(square, [1, 2, 3, 4]))
Kann Multithreading in Python die Ausführung von rechenintensiven Aufgaben beschleunigen?
Antwort: Nein, wegen GIL in der Standardimplementierung von Python (CPython) bieten Threads keinen Leistungszuwachs bei CPU-bound Aufgaben; für solche Aufgaben verwenden Sie multiprocessing oder alternative Implementierungen des Interpreters (z. B. Jython, IronPython), die kein GIL haben.
Geschichte
In einem Projekt zur Verarbeitung großer Datenmengen versuchte das Team, die Berechnungen mithilfe von Threads (
threading) zu beschleunigen. Anstatt die Ausführung zu beschleunigen, wurde die Laufzeit verlängert, da GIL verhinderte, dass Threads parallel arbeiten konnten; nach dem Wechsel zumultiprocessingwurde das Problem gelöst.
Geschichte
Ein Entwickler versuchte, große Dateien gleichzeitig herunterzuladen und diese in mehreren Threads zu verarbeiten, stieß jedoch häufig auf "Deadlocks" aufgrund unvorsichtiger Nutzung gemeinsamer Variablen ohne SperREN (Thread-Sicherheit).
Geschichte
Auf dem Backend-Server wurde die Verarbeitung schwerer Anfragen in einem Thread-Pool implementiert. Bei zunehmender Last begann der Server zu "stocken" – es stellte sich heraus, dass die meisten Threads in der Warteschlange für die Ausführung von Python-Code aufgrund von GIL verbrachten, obwohl die Anfragen nicht mit intensivem I/O verbunden waren.