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
- Erhöhte Geschwindigkeit von Single-Thread-Programmen.
- Einfache Integration von C-Bibliotheken, die normalerweise nicht threadsicher sind.
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.