Ruby Academy · Oppitunti

GVL selitettynä

Miksi säikeet ovat rajoitettuja.

Oppitunti 2/413 vaihetta

GVL selitettynä on ilmainen Ruby Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Ruby Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Ruby Academy-kurssilla on yhteensä 4 oppituntia.

Mikä on GVL?

GVL (Global VM Lock, aiemmin GIL) on CRubyn eli tavallisen Ruby-tulkin sisäinen lukko.

  • Se sallii vain yhden säikeen suorittaa Ruby-koodia kerrallaan.
  • Se suojaa tulkin sisäisiä rakenteita samanaikaisen vioittumisen varalta.
  • Sen vuoksi puhdas Ruby-koodin CPU-työ ei suoritu aidosti rinnakkain useilla ytimillä.

GVL:n ymmärtäminen selittää, milloin säikeistä on hyötyä ja milloin ei.

Miksi se on olemassa

CRubyn sisäisiä toimintoja, kuten olioiden varausta, roskienkeräystä ja C-laajennuksia, ei ole kaikkia kirjoitettu säieturvallisiksi. GVL tekee niistä turvallisia sarjoittamalla Rubyn suorituksen.

GVL:n siisti poistaminen on vaikeaa, joten CRuby käyttää sitä edelleen. JRubylla ja TruffleRubylla ei ole GVL:ää, joten ne voivat suorittaa säikeitä useilla ytimillä.

CPU-painotteinen työ

CPU-painotteisissa tehtävissä, kuten laskennassa, lajittelussa ja jäsentämisessä, säikeet eivät nopeuta suoritusta CRubyssä. Koska vain yksi säie suorittaa Ruby-koodia kerrallaan, kaksi CPU-säiettä vastaavat karkeasti yhtä säiettä ja sen lisäksi syntyvää lisäkustannusta.

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 vapauttaa GVL:n

Keskeinen havainto on, että blokkaava I/O vapauttaa GVL:n. Kun säie nukkuu, lukee tiedostoa tai odottaa socketia, se vapauttaa lukon, jotta toinen säie voi suorittaa Ruby-koodia.

Siksi säikeet sopivat erinomaisesti I/O-painotteiseen työhön myös GVL:n kanssa.

Odottamisen limittäminen

Tässä kolme säiettä nukkuu kukin vuorollaan. Koska sleep vapauttaa GVL:n, odotukset limittyvät. Kokonaisaika on noin 0,2 sekuntia, ei 0,6 sekuntia.

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-laajennukset voivat vapauttaa sen

Hyvin kirjoitetut C-laajennukset voivat vapauttaa GVL:n pitkien natiivien laskutoimitusten ajaksi käyttämällä komentoa rb_thread_call_without_gvl. Tällöin raskas natiivikoodi voi suorittua rinnakkain Ruby-säikeiden jatkaessa toimintaansa.

Siksi jotkin kirjastot saavuttavat todellisen rinnakkaisuuden myös CRubyssä.

Säikeet vaihtuvat silti

GVL ei jäädytä muita säikeitä ikuisesti edes CPU-työssä. CRuby keskeyttää säikeen ajoittain, jotta jokainen saa vuoronsa. Työ on samanaikaista (lomittunutta), mutta ei rinnakkaista (yhtäaikaista).

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

Samanaikaisuus ja rinnakkaisuus

Kaksi tärkeää käsitettä:

  • Samanaikaisuus: tehtävät edistyvät vuorottelemalla. GVL sallii tämän.
  • Rinnakkaisuus: tehtävät suoritetaan täsmälleen samaan aikaan eri ytimillä. GVL estää tämän Ruby-koodin osalta.

Säikeet tarjoavat samanaikaisuutta; Ractorit tarjoavat rinnakkaisuutta.

GVL:n kiertäminen

Voitte käyttää CRubyssä useita ytimiä CPU-työhön seuraavilla tavoilla:

  • Suorittakaa useita prosesseja (jokaisella on oma GVL:nsä).
  • Käyttäkää Ractoreita prosessin sisäiseen rinnakkaisuuteen.
  • Siirtäkää työ C-laajennuksille, jotka vapauttavat GVL:n.

I/O-työhön tavalliset säikeet riittävät yleensä.

Prosesseilla ei ole yhteistä GVL:ää

Jokainen käyttöjärjestelmän prosessi suorittaa omaa Ruby-virtuaalikonettaan ja käyttää omaa GVL:äänsä. Haarauttaminen luo todellisen rinnakkaisuuden, mutta prosessit eivät jaa muistia ja kuluttavat enemmän resursseja.

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

Strategian valitseminen

Ohje valintaan:

  • Paljon odottamista? Käyttäkää säikeitä.
  • Raskas CPU-työ ja tarve hyödyntää ytimiä? Käyttäkää prosesseja tai Ractoreita.
  • Tarvitsetteko jaettua tilaa? Käyttäkää säikeitä ja Mutex-oliota, mutta huomioikaa GVL:n rajoitukset.

GVL:n tunteminen auttaa välttämään yleisen virheen: CPU-säikeiden suorituskyvyn odottamisen kasvavan lineaarisesti.

Pikatarkistus

Testatkaa, kuinka hyvin ymmärrätte GVL:ää.

Kertaus: GVL

Global VM Lockin tärkeimmät asiat:

  • CRubyssä vain yksi säie suorittaa Ruby-koodia kerrallaan.
  • Se suojaa tulkin sisäisiä rakenteita.
  • Blokkaava I/O vapauttaa sen, mikä mahdollistaa limittäiset odotukset.
  • CPU-painotteinen Ruby-työ ei rinnakkaistu useille ytimille.
  • Käyttäkää prosesseja tai Ractoreita todelliseen rinnakkaisuuteen.

Seuraavaksi tutustumme Fibereihin kevyen yhteistyöhön perustuvan samanaikaisuuden toteuttamiseksi.

Aloita maksutta

Opi Ruby tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
29
Oppitunnit
109

Usein kysytyt kysymykset

Onko oppitunti ”GVL selitettynä” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Ruby Academy-oppimispolun 3 oppituntia, myös oppitunnin “GVL selitettynä”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Ruby Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”GVL selitettynä”?

Miksi säikeet ovat rajoitettuja. Harjoittelet Ruby Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Ruby Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Ruby Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”GVL selitettynä”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Ruby Academy-oppitunnilla?

Kyllä. Jokainen Ruby Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Säikeet
  2. GVL selitettynä
  3. Fiberit
  4. Ractorit
← Takaisin: Ruby Academy