Sobes.tech
Middle+

Hogyan valósul meg a Ruby-ban a preemptív multitasking?

sobes.tech MI

Válasz az MI-től

A "tiszta" Ruby (MRI, JRuby, TruffleRuby) esetében nincs valódi preemptív multitasking a párhuzamos kódvégrehajtásra egy folyamaton belül a Global Interpreter Lock (GIL) miatt. A GIL csak egy szál számára engedélyezi a Ruby-kód végrehajtását egy adott időben.

Azonban, a preemptív multitasking Ruby-ben az input/output szinten létezik. Amikor egy szál blokkoló bemenet/kimenet műveletet végez (például fájl olvasás, hálózati kérés), a GIL felszabadul, lehetővé téve egy másik szálnak Ruby-kód végrehajtását. Ez lehetővé teszi az I/O-alapú műveletek párhuzamos végrehajtását, de nem a CPU-kötött feladatok esetében.

Vannak alternatív Ruby-implementációk (például Rubinius), amelyek megpróbáltak valódi GIL nélküli multitaskot megvalósítani, de ezek nem terjedtek el olyan széles körben, mint az MRI.

A CPU-kötött feladatok párhuzamos végrehajtásához Ruby-ben általában:

  • Folyamatok (fork): Minden folyamatnak saját GIL-je van, ami lehetővé teszi a Ruby-kód párhuzamos végrehajtását. A folyamatok közötti adatcsere explicit mechanizmusokat (IPC) igényel.
  • Külső könyvtárak és C-kiterjesztések: A C-ben megvalósított műveletek a GIL ellenőrzésén kívül futtathatók, biztosítva a párhuzamos végrehajtást.

A Ruby 3.0-ban bevezették a Fibers Scheduler-t, amely lehetővé teszi az aszinkron bemenet/kiadás műveletek végrehajtását fiber-ek és nem blokkoló hívások segítségével. Ez javítja az I/O-kötött feladatok teljesítményét, de nem teszi valóban párhuzamossá a CPU-kötött feladatokat egy folyamaton belül.

# Példa a Ruby MRI-ben használt szálakra I/O-kötött feladatokhoz
require 'net/http'
require 'uri'

urls = %w[http://example.com http://ruby-lang.org]
szálak = urls.map do |url|
  Thread.new do
    uri = URI.parse(url)
    response = Net::HTTP.get_response(uri)
    puts "Letöltve #{url} (Állapot: #{response.code})"
  end
end

szálak.each(&:join)

Tehát, bár Ruby rendelkezik szálakkal való munkára alkalmas eszközökkel, a CPU-kötött feladatok valódi preemptív multitaskingja általában több folyamat használatával vagy GIL nélküli speciális Ruby-implementációkkal érhető el.