Top Qs
Chronologie
Chat
Contexte
Global interpreter lock
architecture d'exécution utilisée par certains langages de programmation interprétés De Wikipédia, l'encyclopédie libre
Remove ads
Le verrou global d'interpréteur ( GIL ) est un mécanisme utilisé dans les interpréteurs de langages informatiques pour synchroniser l'exécution des threads, de sorte qu'un seul thread natif (par processus) puisse exécuter des opérations de base à la fois (telles que l'allocation de mémoire et le comptage de références )[1]. En règle générale, un interpréteur utilisant le GIL ne verra qu'un seul thread s'exécuter à la fois, même s'il s'exécute sur un processeur multicœur. Cependant, certaines implémentations permettent au code gourmand en ressources CPU de libérer le GIL, autorisant ainsi les threads à utiliser plusieurs cœurs. CPython et Ruby MRI sont des interpréteurs bien connus disposant d'un GIL.

Remove ads
Concepts techniques de base
Un verrou global d'interpréteur (GIL) est un verrou d'exclusion mutuelle (mutex) détenu par un thread d'interprétation de langage de programmation afin d'empêcher le partage de code non thread-safe avec d'autres threads. Dans les implémentations avec GIL, il existe toujours un GIL pour chaque processus d'interprétation.
Les applications exécutées sur des systèmes dotés d'un GIL peuvent être conçues pour utiliser des processus distincts afin d'atteindre un parallélisme complet, chaque processus possédant son propre interpréteur et, par conséquent, son propre GIL. Sans cela, le GIL peut constituer un obstacle majeur au parallélisme.
Remove ads
Avantages
Les raisons justifiant l'utilisation d'un verrou d'interpréteur global (GIL) sont les suivantes :
- augmentation de la vitesse des programmes mono-thread (plus besoin d'acquérir ou de libérer des verrous sur toutes les structures de données séparément),
- intégration facile des bibliothèques C qui ne sont généralement pas thread-safe,
- facilité de mise en œuvre (un seul GIL est beaucoup plus simple à mettre en œuvre qu'un interpréteur sans verrou ou utilisant des verrous à grains-fins).
Une solution pour contourner le GIL consiste à créer un interpréteur séparé par thread, ce qui est trop coûteux avec la plupart des langages.
Remove ads
Inconvénients
L'utilisation d'un verrou global d'interpréteur (GIL) dans un langage limite de fait le parallélisme possible puisqu'un unique processus interpréteur peut s'exécuter, c'est-à-dire un seul thread peut évoluer à la fois. Si le processus est presque exclusivement composé de code interprété et n'effectue pas d'appels externes à l'interpréteur susceptibles de bloquer le processus pendant de longues périodes (permettant ainsi au thread de libérer le GIL durant son traitement), le gain de vitesse sera probablement minime lors de son exécution sur une machine multiprocesseur. Quand un thread est particulièrement gourmand en ressources CPU, la signalisation entre threads peut même provoquer des ralentissement significatifs, même sur des processeurs mono-cœur[2]. Une autre situation particulièrement handicapante est lorsqu'un thread natif appelle un processus système bloquant (tel qu'un accès disque), le processus entier est bloqué, même si d'autres threads de l'application sont en attente et pourraient en théorie évoluer.
Exemples
Certaines implémentations de langages qui mettent en œuvre un verrou d'interpréteur global sont CPython, l'implémentation la plus largement utilisée de Python[3],[4], et Ruby MRI, l'implémentation de référence de Ruby (où il est appelé Global VM Lock).
Les équivalents de ces langages basés sur la JVM ( Jython et JRuby ) n'utilisent pas de verrous globaux d'interpréteur. IronPython et IronRuby sont implémentés sur le Dynamic Language Runtime de Microsoft et évitent également l'utilisation d'un GIL[5].
Tcl est un exemple de langage interprété sans GIL, utilisé dans l'outil d'évaluation des performances HammerDB[6].
Remove ads
Exemple de code
Exemple de code en Python. Notez comment un verrou est acquis et libéré entre chaque appel d'instruction. Il utilise l'objet Lock à partir du module threading de Python[7].Ici dès lors qu'un thread prend la priorité d'exécution (il acquiert le verrou), tous les autres threads sont stoppés puisqu'un seul d'entre eux peut être interprété à la fois à cause du GIL.
from threading import Lock
INSTRUCTION_TABLE = { ... }
def execute(bytecode: list) -> None:
"""Execute le code binaire."""
lock = Lock()
for (opcode, args) in bytecode:
# On récupère la priorité pour effectuer les opérations non thread-safe
lock.acquire()
INSTRUCTION_TABLE[opcode](args)
# On la libère pour permettre aux autres threads de s'éxécuter
lock.release()
Remove ads
Développements récents
Compilation multi-thread (Python 3.13 et versions ultérieures)
Dans Python 3.13, une version expérimentale « à threads libres » de CPython a été introduite dans le cadre de la PEP 703 – Rendre le verrou global de l’interpréteur optionnel dans CPython . Cette version permet aux développeurs de compiler Python sans le verrou global de l’interpréteur (GIL), permettant ainsi une véritable exécution parallèle du bytecode Python sur plusieurs cœurs de processeur. Cette fonctionnalité reste expérimentale, mais représente une avancée majeure vers une meilleure gestion de la concurrence dans les futures versions de Python[8].
Remove ads
Voir aussi
- Fils verts
- Verrou global du noyau
Références
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads