Il GVL spiegato
Perché i thread sono limitati
Il GVL spiegato è una lezione Ruby Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Ruby Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Ruby Academy include 4 lezioni in totale.
Che cos'è il GVL?
Il GVL (Global VM Lock, storicamente GIL) è un lock interno a CRuby, l'interprete Ruby standard.
- Consente a un solo thread alla volta di eseguire codice Ruby.
- Protegge le strutture interne dell'interprete dalla corruzione causata dall'esecuzione concorrente.
- Impedisce al lavoro eseguito da puro Ruby vincolato alla CPU di funzionare realmente in parallelo su più core.
Comprendere il GVL permette di capire quando i thread sono utili e quando non lo sono.
Perché esiste
Le strutture interne di CRuby (allocazione degli oggetti, garbage collection, estensioni C) non sono state tutte progettate per essere thread-safe. Il GVL le rende sicure serializzando l'esecuzione di Ruby.
Rimuoverlo in modo corretto è difficile, quindi CRuby lo mantiene. JRuby e TruffleRuby non hanno un GVL e possono eseguire thread su più core.
Attività vincolate alla CPU
Per le attività vincolate alla CPU (calcoli matematici, ordinamento, analisi), i thread non velocizzano l'esecuzione con CRuby. In ogni istante, un solo thread esegue codice Ruby, quindi due thread impegnati nella CPU equivalgono all'incirca a un thread singolo più il sovraccarico.
def heavy
sum = 0
1_000_00.times { |i| sum += i }
sum
end
puts heavy
puts "CPU work does not parallelize under the GVL"L'I/O rilascia il GVL
Il concetto chiave è questo: l'I/O bloccante rilascia il GVL. Quando un thread esegue sleep, legge un file o attende su un socket, rilascia il lock, consentendo a un altro thread di eseguire codice Ruby.
Per questo i thread sono ideali per le attività vincolate all'I/O, anche in presenza del GVL.
Sovrapporre le attese
Qui tre thread eseguono ciascuno uno sleep. Poiché sleep rilascia il GVL, le attese si sovrappongono. Il tempo totale è di circa 0,2 s, 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_sLe estensioni C possono rilasciarlo
Le estensioni C ben scritte possono rilasciare il GVL durante lunghi calcoli nativi usando rb_thread_call_without_gvl. In questo modo il lavoro nativo più impegnativo può essere eseguito in parallelo mentre i thread Ruby continuano a lavorare.
Di conseguenza, alcune librerie ottengono un vero parallelismo anche con CRuby.
I thread continuano ad alternarsi
Anche per il lavoro vincolato alla CPU, il GVL non congela per sempre gli altri thread. CRuby interrompe periodicamente un thread, in modo che ciascuno possa eseguire il proprio turno. Il lavoro è concorrente (le attività si alternano), ma non parallelo (non vengono eseguite simultaneamente).
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(", ")Concorrenza e parallelismo
Due termini importanti:
- Concorrenza: le attività avanzano alternandosi. Il GVL lo consente.
- Parallelismo: le attività vengono eseguite esattamente nello stesso istante su core diversi. Il GVL lo impedisce per il codice Ruby.
I thread offrono concorrenza; i Ractor offrono parallelismo.
Aggirare il GVL
Per utilizzare più core per il lavoro vincolato alla CPU in CRuby, può:
- Eseguire più processi (ognuno ha il proprio GVL).
- Usare i Ractor per ottenere il parallelismo all'interno del processo.
- Delegare il lavoro a estensioni C che rilasciano il GVL.
Per il lavoro di I/O, di solito sono sufficienti i normali thread.
I processi non condividono il GVL
Ogni processo del sistema operativo esegue una propria VM Ruby con il proprio GVL. La creazione di processi tramite fork offre un vero parallelismo, ma i processi non condividono la memoria e utilizzano più risorse.
puts "Main pid: " + Process.pid.to_s
puts "Each forked process has its own independent GVL"Scegliere una strategia
Guida alla scelta:
- Deve gestire molte attese? Usi i thread.
- Il lavoro è fortemente vincolato alla CPU e vuole sfruttare più core? Usi i processi o i Ractor.
- Ha bisogno di uno stato condiviso? Usi i thread con un
Mutex, tenendo però presenti i limiti del GVL.
Conoscere il GVL evita il classico errore di aspettarsi che i thread impegnati nella CPU aumentino le prestazioni in modo lineare.
Verifica rapida
Verifichi la sua comprensione del GVL.
Riepilogo: il GVL
Concetti chiave sul Global VM Lock:
- In CRuby, un solo thread alla volta esegue codice Ruby.
- Protegge le strutture interne dell'interprete.
- L'I/O bloccante lo rilascia, consentendo di sovrapporre le attese.
- Il lavoro Ruby vincolato alla CPU non viene eseguito in parallelo su più core.
- Per ottenere un vero parallelismo, usi i processi o i Ractor.
Ora analizzeremo i Fiber per la concorrenza cooperativa leggera.
Domande Frequenti
La lezione «Il GVL spiegato» è gratuita?
Sì — il testo completo di «Il GVL spiegato» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Ruby Academy, passa a CoddyKit PRO. Il corso Ruby Academy include 4 lezioni in totale.
Cosa imparerò in «Il GVL spiegato»?
Perché i thread sono limitati Eserciti Ruby Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Ruby Academy?
Non è richiesta alcuna esperienza precedente. Ruby Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Il GVL spiegato»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Ruby Academy?
Sì. Ogni lezione Ruby Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.