Sobes.tech
Middle+

Kuidas Ruby-s rakendatakse eelnevat multitaskingut?

sobes.tech AI

Vastus AI-lt

"Puhas" Ruby (MRI, JRuby, TruffleRuby) ei oma tõelist väljaajavat mitmeülesandevõimet ühe protsessi sees, kuna Global Interpreter Lock (GIL) võimaldab korraga täita ainult ühte lõime Ruby-koodi:

Kuid, väljaajav mitmeülesandevõime Ruby-s on olemas sisend-väljundi tasemel. Kui lõim täidab blokeerivat sisend-väljundi operatsiooni (näiteks faili lugemine, võrgupäring), siis GIL vabastatakse, võimaldades teisel lõimel Ruby-koodi täita. See võimaldab saavutada paralleelsust sisend-väljundi operatsioonide jaoks, kuid mitte CPU-põhiste ülesannete jaoks:

On olemas alternatiivseid Ruby teostusi (näiteks Rubinius), mis on püüdnud teostada tõelist väljaajavat mitmeülesandevõimet ilma GIL-ita, kuid need ei ole saavutanud nii laialdast levikut kui MRI:

CPU-põhiste ülesannete paralleelseks täitmiseks Ruby-s kasutatakse tavaliselt:

  • Protsesse (fork) — iga protsessil on oma GIL, mis võimaldab Ruby-koodi paralleelselt täita. Andmete vahetamine protsesside vahel nõuab spetsiifilisi mehhanisme (IPC).
  • Väliseid teeke ja C-l põhinevaid laiendusi — C keeles teostatud operatsioone saab täita väljaspool GIL-i kontrolli, tagades paralleelse täitmise:

Ruby 3.0-s on sisse viidud Fibers Scheduler, mis võimaldab asünkroonselt täita sisend-väljundi operatsioone, kasutades fibereid ja mitteblokeerivaid üleskutseid. See parandab I/O-põhiste ülesannete jõudlust, kuid ei tee CPU-põhiseid ülesandeid tõeliselt paralleelseteks ühes protsessis:

# Näide MRI lõimede kasutamisest I/O-põhiste ülesannete jaoks
require 'net/http'
require 'uri'

urls = %w[http://example.com http://ruby-lang.org]
lõimed = urls.map do |url|
  Thread.new do
    uri = URI.parse(url)
    response = Net::HTTP.get_response(uri)
    puts "Allalaaditud #{url} (Staatus: #{response.code})"
  end
end

lõimed.each(&:join)

Seega, kuigi Ruby-l on tööriistad lõimede jaoks, saavutatakse tõeline väljaajav mitmeprotsessiline täitmine peamiselt mitme protsessi või spetsiaalsete GIL-vaba Ruby teostuste kasutamisega.