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
resumeeyield. - 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
yielde lo riprende chiamandoresume.
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 aresume.fiber.resume(*args): Riprende l’esecuzione del Fiber. Gli argomenti passati aresumediventano il valore restituito daFiber.yieldo 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 ayielddiventano il valore restituito daresume.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.