logo

Was ist GIL in Python? Globale Dolmetschersperre

Dieses Tutorial konzentriert sich auf eines der wichtigen Python-Themen, GIL. Wir werden auch erläutern, wie sich die GIL bei der Code-Implementierung auf die Leistung der Python-Programme auswirkt. Bevor wir uns mit diesem Thema befassen, wollen wir uns einen grundlegenden Überblick über die GIL verschaffen.

int parseint

GIL oder Global Interpreter Lock

Python Global Interpreter Lock oder GIL ist ein wichtiger Bestandteil der Multithreading-Programmierung. Dabei handelt es sich um eine Art Prozesssperre, die bei der Arbeit mit mehreren Prozessen verwendet wird. Es gibt die Kontrolle nur an einen Thread. Im Allgemeinen verwendet Python einen einzelnen Thread, um einen einzelnen Prozess auszuführen. Mit der GIL erhalten wir das gleiche Leistungsergebnis der Single-Thread- und Multi-Thread-Prozesse. Es schränkt das Erreichen von Multithreading in Python ein, da es die Threads verhindert und als einzelner Thread arbeitet.

Hinweis – Python unterstützt kein Multithreading, da Threading-Pakete es uns nicht ermöglichen, mehrere CPU-Kerne zu nutzen.

Warum verwenden Python-Entwickler GIL?

Python bietet die einzigartige Referenzzählerfunktion, die für die Speicherverwaltung verwendet wird. Der Referenzzähler zählt die Gesamtzahl der intern in Python vorgenommenen Referenzen, um einem Datenobjekt einen Wert zuzuweisen. Wenn die Referenzzähler Null erreichen, wird der zugewiesene Speicher des Objekts freigegeben. Sehen wir uns das folgende Beispiel an.

Beispiel -

 import sys a = [] b = a sys.getrefcount(a) 

Das Hauptproblem bei der Referenzzählervariablen besteht darin, dass sie beeinträchtigt werden kann, wenn zwei oder drei Threads versuchen, ihren Wert gleichzeitig zu erhöhen oder zu verringern. Dies wird als Rennbedingung bezeichnet. Wenn dieser Zustand auftritt, kann es zu einem Speicherverlust kommen, der nie freigegeben wird. Es kann zu Abstürzen oder Fehlern im Python-Programm kommen.

GIL hilft uns, eine solche Situation zu beseitigen, indem es Sperren für alle gemeinsam genutzten Datenstrukturen in Threads verwendet, damit diese nicht inkonsistent geändert werden. Python bietet eine einfache Möglichkeit, die GIL zu implementieren, da sie sich mit der threadsicheren Speicherverwaltung befasst. GIL erfordert das Anbieten einer einzelnen Sperre für einen Thread zur Verarbeitung in Python. Es erhöht die Leistung eines Single-Threaded-Programms, da nur eine Sperre verarbeitet werden muss. Es hilft auch bei der Erstellung jedes CPU-gebundenen Programms und verhindert Deadlocks.

Die Auswirkungen auf Multithread-Python-Programme

Es gibt einen Unterschied zwischen CPU-Begrenzungen in ihrer Leistung und E/A-Begrenzungen für ein typisches Python-Programm oder ein beliebiges Computerprogramm. CPU-gebundene Programme bringen die CPU in der Regel an ihre Grenzen. Diese Programme werden im Allgemeinen für mathematische Berechnungen wie Matrixmultiplikationen, Searing, Bildverarbeitung usw. verwendet.

E/A-gebundene Programme sind solche Programme, die Zeit aufwenden, um Eingaben/Ausgaben zu erhalten, die vom Benutzer, der Datei, der Datenbank, dem Netzwerk usw. generiert werden können. Solche Programme müssen eine beträchtliche Zeitspanne warten, bis die Quelle die Eingabe bereitstellt. Andererseits hat die Quelle auch ihre eigene Verarbeitungszeit. Beispiel: Ein Benutzer überlegt, was er als Eingabe eingeben soll.

Lassen Sie uns das folgende Beispiel verstehen.

Beispiel -

 import time from threading import Thread COUNT = 100000000 def countdown(num): while num>0: num -= 1 start_time = time.time() countdown(COUNT) end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Ausgabe:

 Time taken in seconds - 7.422671556472778 

Jetzt ändern wir den obigen Code, indem wir die beiden Threads ausführen.

Beispiel – 2:

 import time from threading import Thread COUNT = 100000000 def countdown(num): while num>0: num -= 1 thread1 = Thread(target=countdown, args=(COUNT//2,)) thread2 = Thread(target=countdown, args=(COUNT//2,)) start_time = time.time() thread1.start() thread2.start() thread1.join() thread2.join() end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Ausgabe:

 Time taken in seconds - 6.90830135345459 

Wie wir sehen können, dauerte die Fertigstellung beider Codes gleich lange. GIL verhinderte, dass die CPU-gebundenen Threads im zweiten Code parallel ausgeführt wurden.

Warum wurde die GIL noch nicht entfernt?

Viele Programmierer beschweren sich darüber, aber Python kann die Änderungen nicht so bedeutend machen wie die Entfernung von GIL. Ein weiterer Grund ist, dass GIL derzeit nicht verbessert wurde. Wenn sich dies in Python 3 ändert, führt dies zu schwerwiegenden Problemen. Anstatt GIL zu entfernen, kann das GIL-Konzept verbessert werden. Laut Guido van Rossom -

int, um Java zu stringen

„Ich würde eine Reihe von Patches in Py3k nur dann begrüßen, wenn die Leistung für ein Single-Thread-Programm (und für ein Multi-Thread-, aber I/O-gebundenes Programm) nicht abnimmt.“

Es gibt auch viele Methoden, die das gleiche Problem lösen, das von der GIL gelöst wurde, aber diese sind schwer zu implementieren.

Wie man mit Pythons GIL umgeht

Die Verwendung von Multiprocessing ist die beste Möglichkeit, das Programm vor GIL zu schützen. Python bietet für jeden auszuführenden Prozess verschiedene Interpreter an, sodass in diesem Szenario jedem Prozess im Multiprocessing ein einzelner Thread bereitgestellt wird. Lassen Sie uns das folgende Beispiel verstehen.

Beispiel -

 from multiprocessing import Pool import time COUNT = 50000000 def countdown(num): while num>0: num -= 1 if __name__ == '__main__': pool = Pool(processes=2) start_time = time.time() r1 = pool.apply_async(countdown, [COUNT//2]) r2 = pool.apply_async(countdown, [COUNT//2]) pool.close() pool.join() end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Ausgabe:

 Time taken in seconds - 3.3707828521728516 

Es mag den Anschein haben, dass die Leistung ordentlich gesteigert wird, aber die Prozessverwaltung hat ihren eigenen Overhead und mehrere Prozesse sind schwerer als mehrere Threads.

Abschluss

In diesem Tutorial haben wir die GIL besprochen und wie wir sie verwenden können. Es gibt einem einzelnen Thread die Kontrolle, um ihn gleichzeitig auszuführen. In diesem Tutorial wurde auch behandelt, warum GIL für Python-Programmierer wichtig ist.