0Pricing
Ruby Academy · Leçon

Le GVL expliqué

Pourquoi les threads sont limités

Le GVL expliqué est une leçon Ruby Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Ruby Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Ruby Academy comprend 4 leçons au total.

Qu’est-ce que le GVL ?

Le GVL (verrou global de la VM, historiquement le GIL) est un verrou présent dans CRuby, l’interpréteur Ruby standard.

  • Il n’autorise qu’un seul fil d’exécution à exécuter du code Ruby à la fois.
  • Il protège les composants internes de l’interpréteur contre la corruption due à l’exécution concurrente.
  • Il signifie que les tâches limitées par le CPU en Ruby pur ne s’exécutent pas réellement en parallèle sur plusieurs cœurs.

Comprendre le GVL permet de savoir quand les fils d’exécution sont utiles et quand ils ne le sont pas.

Pourquoi existe-t-il ?

Les composants internes de CRuby (allocation d’objets, ramasse-miettes et extensions en C) n’ont pas tous été conçus pour être sûrs avec plusieurs fils d’exécution. Le GVL les sécurise en sérialisant l’exécution de Ruby.

Le supprimer proprement est difficile, alors CRuby le conserve. JRuby et TruffleRuby n’ont pas de GVL et peuvent exécuter des fils d’exécution sur de nombreux cœurs.

Tâches limitées par le CPU

Pour les tâches limitées par le CPU (calculs mathématiques, tri et analyse syntaxique), les fils d’exécution n’accélèrent pas l’exécution sous CRuby. Un seul fil exécute du code Ruby à un instant donné ; deux fils consacrés au CPU équivalent donc à peu près à un seul fil, avec un surcoût supplémentaire.

def heavy
  sum = 0
  1_000_00.times { |i| sum += i }
  sum
end

puts heavy
puts "CPU work does not parallelize under the GVL"

Les E/S libèrent le GVL

L’idée essentielle est la suivante : les E/S bloquantes libèrent le GVL. Lorsqu’un fil d’exécution est en pause, lit un fichier ou attend sur une socket, il libère le verrou afin qu’un autre fil puisse exécuter du code Ruby.

C’est pourquoi les fils d’exécution sont très efficaces pour les tâches limitées par les E/S, même avec le GVL.

Chevauchement des attentes

Ici, trois fils d’exécution font chacun une pause. Comme sleep libère le GVL, les attentes se chevauchent. La durée totale est d’environ 0,2 s, et non 0,6 s.

start = Time.now

threads = (1..3).map do
  Thread.new { sleep 0.2 }
end
threads.each(&:join)

elapsed = Time.now - start
puts "Elapsed roughly: " + elapsed.round(1).to_s

Les extensions en C peuvent le libérer

Des extensions en C bien écrites peuvent libérer le GVL pendant de longs calculs natifs à l’aide de rb_thread_call_without_gvl. Cela permet à des tâches natives intensives de s’exécuter en parallèle pendant que les fils d’exécution Ruby continuent leur travail.

Certaines bibliothèques peuvent donc atteindre un véritable parallélisme, même sur CRuby.

Les fils d’exécution continuent de basculer

Même pour les tâches limitées par le CPU, le GVL ne fige pas indéfiniment les autres fils d’exécution. CRuby interrompt périodiquement un fil afin que chacun puisse prendre son tour. Le travail est concurrent (entrelacé), mais pas parallèle (simultané).

results = []
mutex = Mutex.new

threads = (1..3).map do |n|
  Thread.new do
    mutex.synchronize { results << n }
  end
end
threads.each(&:join)

puts "Collected: " + results.sort.join(", ")

Concurrence et parallélisme

Deux termes importants :

  • Concurrence : les tâches progressent en s’entrelaçant. Le GVL l’autorise.
  • Parallélisme : les tâches s’exécutent exactement au même instant sur des cœurs différents. Le GVL l’empêche pour le code Ruby.

Les fils d’exécution vous offrent la concurrence ; les acteurs vous offrent le parallélisme.

Contourner le GVL

Pour utiliser plusieurs cœurs lors de tâches limitées par le CPU dans CRuby, vous pouvez :

  • Exécuter plusieurs processus, chacun ayant son propre GVL.
  • Utiliser des acteurs pour le parallélisme au sein du processus.
  • Déléguer le travail à des extensions en C qui libèrent le GVL.

Pour les tâches d’entrée-sortie, les fils d’exécution classiques sont généralement suffisants.

Les processus n’ont pas de GVL partagé

Chaque processus de l’OS exécute sa propre VM Ruby avec son propre GVL. La création de processus fils permet un véritable parallélisme, mais les processus ne partagent pas la mémoire et utilisent davantage de ressources.

puts "Main pid: " + Process.pid.to_s
puts "Each forked process has its own independent GVL"

Choisir une stratégie

Guide de décision :

  • Beaucoup d’attente ? Utilisez des fils d’exécution.
  • CPU intensif et besoin d’exploiter plusieurs cœurs ? Utilisez des processus ou des acteurs.
  • Besoin d’un état partagé ? Utilisez des fils d’exécution avec un Mutex, tout en tenant compte des limites du GVL.

Connaître le GVL permet d’éviter l’erreur classique qui consiste à s’attendre à ce que les fils d’exécution limités par le CPU évoluent linéairement.

Vérification rapide

Testez votre compréhension du GVL.

Récapitulatif : le GVL

Points essentiels concernant le verrou global de la VM :

  • Dans CRuby, un seul fil d’exécution à la fois exécute du code Ruby.
  • Il protège les composants internes de l’interpréteur.
  • Les E/S bloquantes le libèrent, ce qui permet aux attentes de se chevaucher.
  • Les tâches Ruby limitées par le CPU ne s’exécutent pas en parallèle sur plusieurs cœurs.
  • Utilisez des processus ou des acteurs pour obtenir un véritable parallélisme.

Nous allons maintenant découvrir les fibres, qui permettent une concurrence coopérative légère.

Questions Fréquemment Posées

La leçon « Le GVL expliqué » est-elle gratuite ?

Oui — le texte complet de « Le GVL expliqué » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Ruby Academy, passe à CoddyKit PRO. Le cours Ruby Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Le GVL expliqué » ?

Pourquoi les threads sont limités Tu pratiques Ruby Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Ruby Academy ?

Aucune expérience préalable n'est requise. Ruby Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Le GVL expliqué » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Ruby Academy ?

Oui. Chaque leçon Ruby Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Threads
  2. Le GVL expliqué
  3. Fibres
  4. Ractors
← Retour à Ruby Academy