Hinweis: Wo immer ich erwähne, threadmeine ich speziell Threads in Python, bis dies ausdrücklich angegeben wird.
Threads funktionieren in Python etwas anders, wenn Sie aus dem C/C++Hintergrund kommen. In Python kann zu einem bestimmten Zeitpunkt nur ein Thread ausgeführt werden. Dies bedeutet, dass Threads in Python die Leistung mehrerer Verarbeitungskerne nicht wirklich nutzen können, da Threads aufgrund ihres Designs nicht parallel auf mehreren Kernen ausgeführt werden können.
Da die Speicherverwaltung in Python nicht threadsicher ist, erfordert jeder Thread einen exklusiven Zugriff auf Datenstrukturen im Python-Interpreter. Dieser exklusive Zugriff wird durch einen Mechanismus namens (Global Interpretr Lock) erworben .GIL
Why does python use GIL?
Um zu verhindern, dass mehrere Threads gleichzeitig auf den Interpreter-Status zugreifen und den Interpreter-Status beschädigen.
Die Idee ist, wann immer ein Thread ausgeführt wird (auch wenn es der Hauptthread ist) , eine GIL erfasst wird und nach einem vordefinierten Zeitintervall die GIL vom aktuellen Thread freigegeben und von einem anderen Thread (falls vorhanden) erneut erfasst wird.
Why not simply remove GIL?
Es ist nicht so, dass es unmöglich ist, GIL zu entfernen, es ist nur so, dass wir in diesem Fall mehrere Sperren in den Interpreter einfügen, um den Zugriff zu serialisieren, was selbst eine einzelne Thread-Anwendung weniger leistungsfähig macht.
Daher werden die Kosten für das Entfernen von GIL durch eine verringerte Leistung einer einzelnen Thread-Anwendung bezahlt, was niemals erwünscht ist.
So when does thread switching occurs in python?
Der Thread-Wechsel erfolgt, wenn GIL freigegeben wird. Wann wird GIL freigegeben? Es sind zwei Szenarien zu berücksichtigen.
Wenn ein Thread CPU-gebundene Operationen ausführt (Ex-Bildverarbeitung).
In älteren Python-Versionen wurde die Thread-Umschaltung nach einer festgelegten Anzahl von Python-Anweisungen durchgeführt. Standardmäßig wurde diese 100Option festgelegt. Es stellte sich heraus, dass es keine sehr gute Richtlinie ist, zu entscheiden, wann die Umschaltung erfolgen soll, da für die Ausführung einer einzelnen Anweisung Zeit aufgewendet wurde kann sehr wild von Millisekunde bis zu einer Sekunde sein. Daher ist die Freigabe von GIL nach jeder 100Anweisung unabhängig von der Zeit, die sie für die Ausführung benötigen, eine schlechte Richtlinie.
In neuen Versionen wird anstelle der Befehlsanzahl als Metrik zum Wechseln des Threads ein konfigurierbares Zeitintervall verwendet. Das Standardschaltintervall beträgt 5 Millisekunden. Sie können das aktuelle Schaltintervall mit abrufen sys.getswitchinterval(). Dies kann mit geändert werdensys.setswitchinterval()
Wenn ein Thread einige E / A-gebundene Operationen ausführt (Ex-Dateisystemzugriff oder
Netzwerk-E / A)
GIL wird freigegeben, wenn der Thread darauf wartet, dass der E / A-Vorgang abgeschlossen ist.
Which thread to switch to next?
Der Interpreter hat keinen eigenen Scheduler. Welcher Thread am Ende des Intervalls geplant wird, ist die Entscheidung des Betriebssystems. .