Sobes.tech
Middle+

Cos'è Fiber in Ruby?

sobes.tech AI

Risposta dell'AI

Fiber in Ruby è un leggero thread di esecuzione (coroutine) che consente di creare più thread di esecuzione paralleli all’interno di un singolo processo/thread del sistema operativo. Questo permette di gestire l’ordine di esecuzione del codice, alternando tra Fiber senza coinvolgere il pianificatore del sistema operativo.

Caratteristiche principali di Fiber:

  • Scheduling cooperativo: I Fiber non vengono preemptati dal kernel del sistema operativo. La commutazione tra di essi avviene esplicitamente tramite i metodi resume e yield.
  • Un solo thread: Tutti i Fiber nello stesso thread vengono eseguiti sequenzialmente, ma la commutazione tra di essi crea un’illusione di parallelismo per il codice all’interno del thread.
  • Preservazione dello stato: Fiber ricorda il suo stato (variabili locali, punto di esecuzione) chiamando yield e lo riprende chiamando resume.

Applicazioni di Fiber:

  • Implementazione di codice asincrono: Modellare operazioni non bloccanti senza usare callback o strutture complesse.
  • Iteratori e generatori: Creare iteratori complessi che generano valori su richiesta.
  • Gestione di automi finiti: Modellare stati e transizioni in modo esplicito.

Esempio di utilizzo:

# Creazione di un Fiber
fiber = Fiber.new do
  puts "Ciao da Fiber 1"
  value1 = Fiber.yield(1) # Pausa l’esecuzione, ritorna 1
  puts "Ricevuto da Fiber 1: #{value1}"

  puts "Ciao da Fiber 2"
  value2 = Fiber.yield(2) # Pausa l’esecuzione, ritorna 2
  puts "Ricevuto da Fiber 2: #{value2}"

  puts "Ciao da Fiber 3"
  3 # Termina il Fiber, ritorna 3
end

puts "Main: Prima del primo resume"
result1 = fiber.resume # Riprende l’esecuzione del Fiber
puts "Main: Ricevuto dal Fiber: #{result1}"

puts "Main: Prima del secondo resume"
result2 = fiber.resume("da Main 1") # Riprende e passa valore
puts "Main: Ricevuto dal Fiber: #{result2}"

puts "Main: Prima del terzo resume"
result3 = fiber.resume("da Main 2") # Riprende e passa valore
puts "Main: Ricevuto dal Fiber: #{result3}"

Metodi principali:

  • Fiber.new { ... }: Crea un nuovo Fiber. Il blocco di codice viene eseguito alla prima chiamata a resume.
  • fiber.resume(*args): Riprende l’esecuzione del Fiber. Gli argomenti passati a resume diventano il valore restituito da Fiber.yield o dagli argomenti del blocco che lo ha avviato.
  • Fiber.yield(*args): Pausa l’esecuzione del Fiber corrente e restituisce il controllo al codice che lo ha avviato (resume). Gli argomenti passati a yield diventano il valore restituito da resume.
  • Fiber.current: Restituisce il Fiber corrente.

Differenze tra Fiber e Thread:

Caratteristica Fiber Thread
Pianificazione Cooperativa (cambio esplicito) Preemptive (gestito dal sistema operativo)
Risorse Leggero (meno risorse) Più pesante (più risorse)
Parallelismo Falso parallelismo in un solo thread Vero parallelismo (usa i core CPU)
Comunicazione Tramite yield e resume Tramite memoria condivisa, messaggi, ecc.
Debugging Relativamente più semplice (flusso lineare) Più complesso (condizioni di gara, blocchi)

I Fiber forniscono un meccanismo di controllo dell’esecuzione di livello inferiore rispetto ai Thread, richiedendo una gestione esplicita dei cambi di contesto.