Il existe plusieurs implémentations de Python, par exemple, CPython, IronPython, RPython, etc.
Certains d'entre eux ont un GIL, d'autres non. Par exemple, CPython a le GIL:
De http://en.wikipedia.org/wiki/Global_Interpreter_Lock
Les applications écrites dans des langages de programmation avec GIL peuvent être conçues pour utiliser des processus distincts pour obtenir un parallélisme complet, chaque processus ayant son propre interpréteur et à son tour son propre GIL.
Avantages du GIL
- Augmentation de la vitesse des programmes mono-thread.
- Intégration facile de bibliothèques C qui ne sont généralement pas thread-safe.
Pourquoi Python (CPython et autres) utilise le GIL
Dans CPython, le verrou d'interpréteur global, ou GIL, est un mutex qui empêche plusieurs threads natifs d'exécuter en même temps des bytecodes Python. Ce verrou est nécessaire principalement parce que la gestion de la mémoire de CPython n'est pas thread-safe.
La GIL est controversée car elle empêche les programmes CPython multithreads de tirer pleinement parti des systèmes multiprocesseurs dans certaines situations. Notez que les opérations potentiellement bloquantes ou de longue durée, telles que les E / S, le traitement des images et la réduction du nombre de numéros NumPy, se produisent en dehors de la liste GIL. Par conséquent, ce n'est que dans les programmes multithreads qui passent beaucoup de temps dans GIL, interprétant le bytecode CPython, que GIL devient un goulot d'étranglement.
Python a un code GIL par opposition à un verrouillage à grain fin pour plusieurs raisons:
C'est plus rapide dans le cas des threads simples.
C'est plus rapide dans le cas multithread pour les programmes liés d'E / S.
Il est plus rapide dans le cas multithread des programmes liés à l'unité centrale qui effectuent leur travail de calcul intensif dans les bibliothèques C.
Cela facilite l’écriture des extensions C: il n’y aura pas de changement de threads Python, sauf si vous le permettez (c’est-à-dire entre les macros Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS).
Cela facilite l’emballage des bibliothèques C. Vous n'avez pas à vous soucier de la sécurité du fil. Si la bibliothèque n’est pas thread-safe, vous devez simplement verrouiller la GIL pendant que vous l’appelez.
Le GIL peut être publié par les extensions C. La bibliothèque standard de Python libère le GIL autour de chaque appel d'E / S bloquant. Ainsi, le GIL n'a aucune conséquence sur les performances des serveurs liés d'E / S. Vous pouvez ainsi créer des serveurs de réseau en Python à l'aide de processus (fork), de threads ou d'entrées / sorties asynchrones. GIL ne vous gênera pas.
Les bibliothèques numériques en C ou en Fortran peuvent également être appelées avec la version GIL publiée. Pendant que votre extension C attend la fin d'une FFT, l'interpréteur exécutera d'autres threads Python. Un GIL est donc plus facile et plus rapide qu'un verrouillage fin dans ce cas également. Ceci constitue l'essentiel du travail numérique. L'extension NumPy libère le GIL chaque fois que possible.
Les threads sont généralement un mauvais moyen d'écrire la plupart des programmes serveur. Si la charge est faible, le forgeage est plus facile. Si la charge est élevée, la programmation asynchrone des entrées / sorties et des événements (par exemple, à l'aide de la structure Twisted de Python) est préférable. La seule excuse pour utiliser des threads est le manque de os.fork sous Windows.
La GIL pose un problème si, et seulement si, vous effectuez un travail gourmand en ressources processeur en Python pur. Ici, vous pouvez obtenir une conception plus propre en utilisant des processus et la transmission de messages (par exemple, mpi4py). Il existe également un module de «traitement» dans la fromagerie Python, qui donne aux processus la même interface que les threads (c'est-à-dire, remplacez threading.Thread par processing.Process).
Les threads peuvent être utilisés pour maintenir la réactivité d'une interface graphique indépendamment de la GIL. Si le GIL altère votre performance (voir la discussion ci-dessus), vous pouvez laisser votre thread générer un processus et attendre qu'il se termine.