Accéder au contenu principal

Tutoriel sur le Global Interpreter Lock de Python

Découvrez ce qu’est le Global Interpreter Lock, comment il fonctionne et pourquoi l’utiliser.
Actualisé 19 sept. 2026  · 8 min lire

Explorer avec l’IA

ChatGPTClaudePerplexity

Si vous débutez en Python et souhaitez aller plus loin, suivez le cours Introduction to Data Science in Python de DataCamp.

Un Global Interpreter Lock (GIL) est un mécanisme qui applique un verrou global à un interpréteur. Il est utilisé dans certains interpréteurs de langages pour synchroniser et gérer l’exécution des threads afin qu’un seul thread natif (planifié par le système d’exploitation) puisse s’exécuter à la fois.

Dans un contexte multi-threads, deux threads peuvent tenter d’accéder en même temps à la même zone mémoire et, ce faisant, écraser les données en mémoire. Il faut donc un mécanisme pour éviter ce phénomène.

Parmi les interpréteurs connus qui utilisent un GIL, on trouve CPython et Ruby MRI. Comme vous le savez, Python est un langage interprété et propose plusieurs implémentations comme CPython, Jython, IronPython. Parmi celles-ci, seul CPython implémente le GIL, et c’est aussi l’implémentation de Python la plus utilisée. CPython est développé en C et en Python, principalement pour bien s’interfacer avec des applications ayant beaucoup de code C sous le capot.

Même si votre processeur possède plusieurs cœurs, un interpréteur avec GIL n’autorisera l’exécution que d’un seul thread à la fois. En effet, lorsqu’un thread démarre, il acquiert le GIL. Lorsqu’il attend une opération d’E/S (lecture/écriture sur disque) ou qu’il exécute une opération coûteuse en CPU (multiplication vecteur/matrice), il libère le verrou afin que d’autres threads du processus puissent s’exécuter. Cela empêche donc l’exécution simultanée de plusieurs threads.

thread

Prenons un instant pour comprendre le schéma ci-dessus. On y voit une fonction factorial et deux threads 1 et 2 : le thread 1 est en état verrouillé tandis que le thread 2 est en attente. Cela signifie qu’un seul thread peut accéder à la fonction. Supposons maintenant que la fonction factorial prenne 2 secondes. Dans un cas idéal, les deux threads devraient terminer en 2 secondes. Or, en Python, ce n’est pas le cas : les deux threads s’exécutent en série et non en parallèle.

Les threads 1 et 2 appelant la fonction factorial peuvent prendre deux fois plus de temps qu’un seul thread appelant la même fonction deux fois. Cela montre aussi que le gestionnaire mémoire piloté par l’interpréteur n’est pas thread-safe : plusieurs threads ne peuvent pas accéder simultanément aux mêmes données partagées.

Ainsi, le GIL (Source : Understanding the Python GIL) :

  • Limite l’usage des threads.

  • Restreint l’exécution en parallèle.

  • Garantit qu’un seul thread s’exécute dans l’interpréteur à un instant donné.

  • Simplifie divers aspects bas niveau comme la gestion de la mémoire.

Avec le GIL, on obtient un multitâche coopératif et coordonné, plutôt qu’un calcul parallèle.

gil
Source</a

Comme on peut le voir sur le schéma ci-dessus, trois threads sont en jeu : initialement, le thread 1 s’exécute et a acquis le GIL. Lorsqu’une opération d’E/S (lecture, écriture, etc.) survient, le thread 1 libère le GIL, qui est alors acquis par le thread 2. Ce cycle se répète, et le GIL passe d’un thread à l’autre jusqu’à ce que tous aient terminé l’exécution du programme. Rappelez-vous : tout thread qui n’a pas le verrou et n’a pas fini son exécution reste en attente.

GIL dans Python 2 vs Python 3
gil

Le Global Interpreter Lock de Python 2.7 fonctionne différemment de celui de Python 3. Dans un traitement purement lié au CPU, le thread continue de tourner puisqu’il n’y a pas d’opérations d’E/S ; les autres threads restent donc en veille ou en attente, ce qui n’est pas souhaitable. Pour pallier cela, Python 2 utilise la notion de ticks. Le GIL effectue un contrôle périodique de l’état des threads (attente, E/S, exécution). Il ne surveille pas en continu : il s’appuie sur des ticks et vérifie les threads toutes les 100 instructions.

Un tick correspond à une instruction de bytecode. Quand 100 instructions de bytecode sont exécutées, le GIL vérifie si les threads tournent ou attendent. Important : un tick n’est pas lié au temps réel puisqu’il s’agit d’une instruction de bytecode. Chaque tick peut durer plus ou moins longtemps qu’un autre.

gil
Source</a

Ce contrôle périodique toutes les 100 instructions est essentiel, surtout pour les tâches CPU-bound qui n’impliquent pas d’E/S. Notez que vous pouvez modifier ce compteur via le module standard sys de Python.

gil
Source</a

Voyons quelques limites de cette approche :

Dans ce schéma, on constate que les threads ne s’exécutent pas en parallèle mais en série : un multitâche coopératif régi par le GIL. Les threads doivent aussi patienter plus longtemps. Par exemple, le thread T3 doit attendre que T1 puis T2 libèrent le GIL. Les threads « affament » ainsi le verrou et le temps de calcul.

Autre inconvénient : les threads se disputent l’acquisition du GIL. Au départ, T1 peut l’obtenir selon sa priorité, puis T2, etc. Cependant, quand T3 libère le GIL, il notifie tous les autres threads, qui se remettent en concurrence pour l’acquérir. Vous pouvez toutefois atténuer cela en définissant des priorités de thread.

Dans Python 3, un quantum de temps fixe est alloué à chaque thread (environ 5 ms d’exécution). Cela évite que les threads soient privés de ressources, puisque le temps d’attente est égal pour tous. Les threads attendent de voir si Thread 1 libère le GIL de lui-même (E/S, sleep). Sinon, il sera forcé de le libérer après 5 ms. Ainsi, pas de famine de temps CPU : chaque thread obtient une part égale, ce qui réduit la contention autour du GIL.

gil

Notez toutefois que la nouvelle implémentation du GIL privilégie davantage les tâches CPU-bound par rapport aux opérations d’E/S. Si un thread a libéré le GIL et que deux threads attendent, celui qui doit exécuter une tâche gourmande en CPU aura tendance à récupérer le GIL en priorité.

Conclusion

Félicitations pour avoir terminé ce tutoriel.

Nous avons abordé un sujet avancé avec pour objectif de vous offrir une vue théorique du fonctionnement du GIL en Python. Comme nous n’avons pas traité la partie code autour du GIL et des threads, un bon exercice consiste à expérimenter : créez plusieurs threads et une méthode réalisant une tâche intensive en E/S, puis analysez comment le GIL passe d’un thread à l’autre.

N’hésitez pas à poser vos questions sur ce tutoriel dans les commentaires ci-dessous.

Références :

Si vous débutez en Python et souhaitez en apprendre davantage, suivez le cours Introduction to Data Science in Python de DataCamp.

Sujets
Python

Cours Python

Cours

Introduction à Python

4 h
7M
Apprenez les bases de l’analyse de données avec Python en quatre heures et explorez ses principaux packages.
Afficher les détailsRight Arrow
Commencer Le Cours
Voir plusRight Arrow