Die globale Interpreter-Sperre (GIL) wird anscheinend häufig als Hauptgrund dafür angeführt, dass Threading und dergleichen in Python schwierig ist - was die Frage aufwirft, warum dies überhaupt geschehen ist.
Da ich kein Programmierer bin, habe ich keine Ahnung, warum das so ist - was war die Logik, die dahinter steckt, die GIL einzufügen?
python
multithreading
Fomite
quelle
quelle
Antworten:
Es gibt verschiedene Implementierungen von Python, z. B. CPython, IronPython, RPython usw.
Einige von ihnen haben eine GIL, andere nicht. Zum Beispiel hat CPython die GIL:
Aus http://en.wikipedia.org/wiki/Global_Interpreter_Lock
In Programmiersprachen mit einer GIL geschriebene Anwendungen können so entworfen werden, dass separate Prozesse verwendet werden, um eine vollständige Parallelität zu erreichen, da jeder Prozess seinen eigenen Interpreter und wiederum seine eigene GIL hat.
Vorteile der GIL
Warum verwendet Python (CPython und andere) die GIL?
In CPython ist die globale Interpretersperre (GIL) ein Mutex, der verhindert, dass mehrere native Threads Python-Bytecodes gleichzeitig ausführen. Diese Sperre ist hauptsächlich notwendig, weil die Speicherverwaltung von CPython nicht threadsicher ist.
Die GIL ist umstritten, da sie verhindert, dass Multithread-CPython-Programme in bestimmten Situationen die Multiprozessorsysteme voll ausnutzen. Beachten Sie, dass potenziell blockierende oder lang andauernde Vorgänge wie E / A, Bildverarbeitung und NumPy-Zahlenverarbeitung außerhalb der GIL stattfinden. Daher wird nur in Multithread-Programmen, die viel Zeit in der GIL verbringen und den CPython-Bytecode interpretieren, die GIL zu einem Engpass.
Python hat aus mehreren Gründen eine GIL im Gegensatz zu einer feinkörnigen Sperrung:
Im Single-Threaded-Fall ist es schneller.
Im Multithread-Fall ist es für i / o-gebundene Programme schneller.
Im Multithreading-Fall ist es schneller, wenn cpu-gebundene Programme ihre rechenintensive Arbeit in C-Bibliotheken ausführen.
Dies erleichtert das Schreiben von C-Erweiterungen: Python-Threads werden nur dort umgeschaltet, wo Sie dies zulassen (dh zwischen den Makros Py_BEGIN_ALLOW_THREADS und Py_END_ALLOW_THREADS).
Dies erleichtert das Umschließen von C-Bibliotheken. Sie müssen sich keine Sorgen um die Thread-Sicherheit machen. Wenn die Bibliothek nicht threadsicher ist, lassen Sie die GIL einfach gesperrt, während Sie sie aufrufen.
Die GIL kann durch C-Erweiterungen freigegeben werden. Die Standardbibliothek von Python gibt die GIL für jeden blockierenden E / A-Aufruf frei. Somit hat die GIL keine Konsequenzen für die Leistung von I / O-gebundenen Servern. Auf diese Weise können Sie Netzwerkserver in Python mithilfe von Prozessen (Fork), Threads oder asynchronen E / A erstellen, und die GIL wird nicht in die Quere kommen.
Numerische Bibliotheken in C oder Fortran können ebenfalls mit der veröffentlichten GIL aufgerufen werden. Während Ihre C-Erweiterung auf den Abschluss einer FFT wartet, führt der Interpreter andere Python-Threads aus. Eine GIL ist somit auch in diesem Fall einfacher und schneller als eine feinkörnige Verriegelung. Dies macht den Großteil der numerischen Arbeit aus. Die NumPy-Erweiterung gibt die GIL nach Möglichkeit frei.
Threads sind normalerweise ein schlechter Weg, um die meisten Serverprogramme zu schreiben. Bei geringer Last ist das Gabeln einfacher. Bei hoher Auslastung ist eine asynchrone E / A- und ereignisgesteuerte Programmierung (z. B. mit dem Twisted-Framework von Python) besser. Die einzige Entschuldigung für die Verwendung von Threads ist das Fehlen von os.fork unter Windows.
Die GIL ist nur dann ein Problem, wenn Sie in reinem Python CPU-intensive Arbeit leisten. Hier können Sie mithilfe von Prozessen und Message-Passing (z. B. mpi4py) ein saubereres Design erzielen. Es gibt auch ein "Processing" -Modul in Python Cheese Shop, das Prozessen die gleiche Schnittstelle wie Threads gibt (dh threading.Thread durch processing.Process ersetzen).
Threads können verwendet werden, um die Reaktionsfähigkeit einer GUI unabhängig von der GIL aufrechtzuerhalten. Wenn die GIL Ihre Leistung beeinträchtigt (siehe obige Diskussion), können Sie Ihren Thread einen Prozess spawnen lassen und warten, bis er beendet ist.
quelle
s/RPython/PyPy/g
. @MichaelBorgwardt Gründe für GIL zu nennen, ist eine Frage, nicht wahr? Ich stimme jedoch zu, dass ein Teil des Inhalts dieser Antwort (nämlich die Erörterung von Alternativen) nicht relevant ist. Und zum Guten oder Schlechten ist es jetzt fast unmöglich, das Nachzählen wieder loszuwerden - es ist tief in der gesamten API- und Codebasis verankert. Es ist fast unmöglich, es loszuwerden, ohne den halben Code neu zu schreiben und den gesamten externen Code zu brechen .multiprocessing
Bibliothek - Standard seit 2.6. Die Worker-Pools sind für einige einfache Arten von Parallelität eine sehr raffinierte Abstraktion.Zunächst einmal: Python hat keine GIL. Python ist eine Programmiersprache. Eine Programmiersprache ist ein Satz abstrakter mathematischer Regeln und Einschränkungen. In der Python-Sprachspezifikation gibt es nichts, was besagt, dass es eine GIL geben muss.
Es gibt viele verschiedene Implementierungen von Python. Einige haben eine GIL, andere nicht.
Eine einfache Erklärung für eine GIL ist, dass das Schreiben von gleichzeitigem Code schwierig ist. Wenn Sie Ihren Code mit einem riesigen Schloss versehen, wird er immer seriell ausgeführt. Problem gelöst!
Insbesondere in CPython ist es ein wichtiges Ziel, die Erweiterung des Interpreters um in C geschriebene Plugins zu vereinfachen. Auch hier ist das Schreiben von gleichzeitigem Code schwierig. Dadurch, dass sichergestellt wird, dass es keine Parallelität gibt, wird das Schreiben von Erweiterungen vereinfacht der Dolmetscher. Außerdem handelt es sich bei vielen dieser Erweiterungen nur um dünne Wrapper um vorhandene Bibliotheken, die möglicherweise nicht unter Berücksichtigung der Parallelität geschrieben wurden.
quelle
Was ist der Zweck einer GIL?
Die CAPI-Dokumentation hat zu diesem Thema folgendes zu sagen:
Mit anderen Worten, die GIL verhindert die Korruption des Staates. Python-Programme sollten niemals einen Segmentierungsfehler erzeugen, da nur speichersichere Operationen zulässig sind. Die GIL erweitert diese Sicherheit auf Multithread-Programme.
Was sind die Alternativen?
Wenn der Zweck der GIL darin besteht, den Staat vor Korruption zu schützen, dann ist eine naheliegende Alternative, sich auf ein viel feineres Korn festzulegen. Vielleicht auf Objektebene. Das Problem dabei ist, dass, obwohl nachgewiesen wurde, dass es die Leistung von Multithread-Programmen erhöht, der Overhead zunimmt und Single-Thread-Programme darunter leiden.
quelle