Fan-out e fan-in
Distribuire e raccogliere il lavoro
Fan-out e fan-in è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.
Fan-out e fan-in
Fan-out significa avviare diverse goroutine che leggono da un unico canale, distribuendo il lavoro. Fan-in significa riunire gli output di diverse goroutine in un unico canale.
- Il fan-out distribuisce il carico tra i worker
- Il fan-in riunisce i risultati per il consumer
Una fase generatrice
La pipeline inizia con un generatore: una funzione che restituisce un canale e vi inserisce valori dalla propria goroutine, quindi lo chiude.
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}Fan-out
Per realizzare il fan-out, avvii più goroutine che leggono tutte dallo stesso canale di input. Ognuna esegue la stessa funzione di elaborazione e produce il proprio canale di output.
in := gen(1, 2, 3, 4, 5)
c1 := square(in)
c2 := square(in)Una fase di elaborazione
La fase square legge da in, eleva al quadrato ogni valore e lo invia a un nuovo canale di output. Più istanze di questa fase condividono un unico input.
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}Fan-in con merge
Il fan-in riunisce diversi canali in uno solo. Un sync.WaitGroup tiene traccia delle goroutine associate a ciascun canale, mentre una goroutine di chiusura attende che tutte terminino prima di chiudere l'output riunito.
func merge(cs ...<-chan int) <-chan int {
out := make(chan int)
var wg sync.WaitGroup
for _, c := range cs {
wg.Add(1)
go func(c <-chan int) {
for n := range c {
out <- n
}
wg.Done()
}(c)
}
go func() { wg.Wait(); close(out) }()
return out
}Perché usare WaitGroup
Ogni goroutine di unione copia un canale di input in out. Non bisogna chiudere out finché tutti gli input non sono stati svuotati. Il WaitGroup conta i copier attivi; la goroutine di chiusura si blocca su wg.Wait() finché non terminano.
Catturare la variabile del ciclo
Nelle versioni precedenti di Go, la closure deve ricevere c come parametro, così ogni goroutine associa il proprio canale invece di utilizzare la variabile del ciclo condivisa. Passare c esplicitamente evita il classico bug della variabile del ciclo.
Un fan-out fan-in completo
Questo programma genera numeri, esegue il fan-out verso due fasi square, quindi esegue il fan-in e somma i risultati riuniti.
package main
import (
"fmt"
"sync"
)
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() { for _, n := range nums { out <- n }; close(out) }()
return out
}
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() { for n := range in { out <- n * n }; close(out) }()
return out
}
func merge(cs ...<-chan int) <-chan int {
out := make(chan int)
var wg sync.WaitGroup
for _, c := range cs {
wg.Add(1)
go func(c <-chan int) { for n := range c { out <- n }; wg.Done() }(c)
}
go func() { wg.Wait(); close(out) }()
return out
}
func main() {
in := gen(1, 2, 3, 4, 5)
c1 := square(in)
c2 := square(in)
total := 0
for n := range merge(c1, c2) {
total += n
}
fmt.Println("sum of squares:", total)
}L'ordine non è garantito
Poiché le due fasi square competono per lo stesso input, l'ordine dell'output riunito è non deterministico. Se è necessario mantenere l'ordine, associ un indice a ogni elemento oppure utilizzi una singola fase.
Quando usare il fan-out
Utilizzi il fan-out quando una fase costituisce il collo di bottiglia e il lavoro può essere parallelizzato. Se il generatore a monte è lento, aggiungere altri worker a valle non sarà utile: rimarranno semplicemente inattivi in attesa di lavoro.
Backpressure
I canali non bufferizzati creano una backpressure naturale: una fase veloce si blocca quando un consumer lento non riesce a tenere il passo. In questo modo si evita una crescita illimitata della memoria lungo la pipeline.
Verifica rapida
Verifichi la Sua conoscenza del fan-in.
Riepilogo
Ha imparato il fan-out e il fan-in:
- Fan-out: più goroutine leggono da un unico canale
- Fan-in: riunire molti canali in uno solo tramite WaitGroup
- L'ordine non viene mantenuto tra le fasi parallele
- I canali non bufferizzati forniscono backpressure
Domande Frequenti
La lezione «Fan-out e fan-in» è gratuita?
Sì — il testo completo di «Fan-out e fan-in» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.
Cosa imparerò in «Fan-out e fan-in»?
Distribuire e raccogliere il lavoro Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Go Academy?
Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Fan-out e fan-in»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Go Academy?
Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Pattern del worker pool
- Fan-out e fan-in
- Fasi della pipeline
- Arresto graduale