Ruby Academy · Lektion

GVL förklarad

Varför trådar är begränsade.

Lektion 2 av 413 steg

GVL förklarad är en gratis lektion i Ruby Academy på CoddyKit. Detta är lektion 2 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Ruby Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Ruby Academy innehåller totalt 4 lektioner.

Vad är GVL?

GVL (Global VM Lock, historiskt GIL) är ett lås inuti CRuby, den vanliga Ruby-tolken.

  • Det tillåter endast en tråd att köra Ruby-kod åt gången.
  • Det skyddar tolkens interna delar mot samtidig korruption.
  • Det innebär att CPU-arbete i ren Ruby inte verkligen körs parallellt på flera kärnor.

Genom att förstå GVL blir det tydligt när trådar hjälper och när de inte gör det.

Varför det finns

CRubys interna delar (objektallokering, skräpsamling och C-tillägg) skrevs inte alla för att vara trådsäkra. GVL gör dem säkra genom att serialisera Ruby-körningen.

Det är svårt att ta bort GVL på ett robust sätt, så CRuby behåller det. JRuby och TruffleRuby har inget GVL och kan köra trådar på många kärnor.

CPU-bundet arbete

För CPU-bundna uppgifter (matematik, sortering och tolkning) gör trådar inte arbetet snabbare i CRuby. Bara en tråd åt gången kör Ruby-kod, så två CPU-trådar motsvarar ungefär en tråd plus extra kostnader.

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

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

I/O frigör GVL

Den viktiga insikten är att blockerande I/O frigör GVL. När en tråd sover, läser en fil eller väntar på ett uttag släpper den låset, så att en annan tråd kan köra Ruby-kod.

Därför är trådar utmärkta för I/O-bundet arbete även med GVL.

Överlappande väntetider

Här sover tre trådar. Eftersom sleep frigör GVL överlappar väntetiderna varandra. Den totala tiden är ungefär 0,2 sekunder, inte 0,6 sekunder.

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

C-tillägg kan frigöra det

Välskrivna C-tillägg kan frigöra GVL under långa beräkningar i inbyggd kod med hjälp av rb_thread_call_without_gvl. Det gör att tungt arbete i inbyggd kod kan köras parallellt medan Ruby-trådar fortsätter.

På så sätt kan vissa bibliotek uppnå verklig parallellism även i CRuby.

Trådar växlar ändå

Även vid CPU-arbete fryser GVL inte andra trådar för alltid. CRuby avbryter en tråd med jämna mellanrum så att alla får sin tur. Arbetet är samtidigt (interfolierat), men inte parallellt (samtidigt på riktigt).

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(", ")

Samtidighet kontra parallellism

Två viktiga begrepp:

  • Samtidighet: uppgifter gör framsteg genom att växla mellan varandra. GVL tillåter detta.
  • Parallellism: uppgifter körs exakt samtidigt på olika kärnor. GVL förhindrar detta för Ruby-kod.

Trådar ger dig samtidighet; Ractors ger dig parallellism.

Runt GVL

Om du vill använda flera kärnor för CPU-arbete i CRuby kan du:

  • Köra flera processer (var och en har sitt eget GVL).
  • Använda Ractors för parallellism i samma process.
  • Flytta arbetet till C-tillägg som frigör GVL.

För I/O-arbete räcker vanliga trådar oftast.

Processer har inget gemensamt GVL

Varje operativsystemsprocess kör sin egen Ruby-VM med sitt eget GVL. Att skapa processer genom fork ger verklig parallellism, men processer delar inte minne och använder mer resurser.

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

Välja strategi

Vägledning för valet:

  • Mycket väntan? Använd trådar.
  • Tungt CPU-arbete och behov av flera kärnor? Använd processer eller Ractors.
  • Behöver du delat tillstånd? Använd trådar med en Mutex, men tänk på GVL:s begränsningar.

Genom att känna till GVL undviker du det klassiska misstaget att förvänta dig linjär skalning med CPU-trådar.

Snabbtest

Testa dina kunskaper om GVL.

Sammanfattning: GVL

Viktiga slutsatser om Global VM Lock:

  • Bara en tråd åt gången kör Ruby-kod i CRuby.
  • Det skyddar tolkens interna delar.
  • Blockerande I/O frigör det, vilket möjliggör överlappande väntetider.
  • CPU-bundet Ruby-arbete parallelliseras inte över flera kärnor.
  • Använd processer eller Ractors för verklig parallellism.

Härnäst tittar vi på fibrer för lättviktig kooperativ samtidighet.

Gratis att börja

Lär dig Ruby med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
29
Lektioner
109

Vanliga frågor

Är lektionen ”GVL förklarad” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Ruby Academy, inklusive ”GVL förklarad”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Ruby Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”GVL förklarad”?

Varför trådar är begränsade. Ni övar på Ruby Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Ruby Academy?

Du behöver inga förkunskaper. Utbildningen i Ruby Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”GVL förklarad”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Ruby Academy-lektionen?

Ja. Varje Ruby Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Trådar
  2. GVL förklarad
  3. Fibers
  4. Ractors
← Tillbaka till Ruby Academy