Fan-out e fan-in
Distribua e reúna o trabalho
Fan-out e fan-in é uma aula grátis de Go Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Go Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Go Academy inclui 4 aulas no total.
Distribuição e agregação
Distribuição significa iniciar várias gorrotinas para ler de um canal, distribuindo o trabalho. Agregação significa reunir as saídas de várias gorrotinas novamente em um único canal.
- A distribuição espalha a carga entre os workers
- A agregação consolida os resultados para o consumidor
Uma stage geradora
O fluxo de processamento começa com uma geradora: uma função que retorna um canal, envia valores para ele a partir de sua própria gorrotina e então o fecha.
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}Distribuindo
Para distribuir, inicie várias gorrotinas que leiam todas do mesmo canal de entrada. Cada uma executa a mesma função de processamento e produz seu próprio canal de saída.
in := gen(1, 2, 3, 4, 5)
c1 := square(in)
c2 := square(in)Uma stage de processamento
A stage square lê de in, eleva cada valor ao quadrado e o envia para um novo canal de saída. Várias instâncias dessa stage compartilham uma única entrada.
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}Agregando com merge
A agregação reúne vários canais em um só. Um sync.WaitGroup acompanha as gorrotinas de cada canal, e uma gorrotina de fechamento espera por todas elas antes de fechar a saída agregada.
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
}Por que usar WaitGroup
Cada gorrotina de agregação copia um canal de entrada para out. Não devemos fechar out até que todas as entradas sejam esgotadas. O WaitGroup conta os copiadores ativos; a gorrotina de fechamento fica bloqueada em wg.Wait() até que eles terminem.
Capturando a variável do loop
Em versões antigas de Go, o fechamento deve receber c como parâmetro para que cada gorrotina associe seu próprio canal, em vez da variável compartilhada do loop. Passar c explicitamente evita o conhecido bug da variável do loop.
Uma distribuição e agregação completas
Este programa gera números, distribui o trabalho para duas stages square, depois agrega os resultados e soma a saída reunida.
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)
}A ordem não é garantida
Como duas stages square competem pela mesma entrada, a ordem da saída agregada é não determinística. Se você precisar preservar a ordem, associe um índice a cada item ou use uma única stage.
Quando distribuir
Distribua o trabalho quando uma stage for o gargalo e o trabalho puder ser paralelizado. Se a geradora upstream for lenta, adicionar mais workers downstream não ajudará; eles apenas ficarão sem trabalho.
Contrapressão
Canais sem buffer criam uma contrapressão natural: uma stage rápida fica bloqueada quando um consumidor lento não consegue acompanhá-la. Isso impede o crescimento ilimitado da memória ao longo do fluxo de processamento.
Verificação rápida
Avalie seu conhecimento sobre agregação.
Recapitulação
Você aprendeu sobre distribuição e agregação:
- Distribuição: várias gorrotinas leem de um canal
- Agregação: reúna muitos canais em um só usando WaitGroup
- A ordem não é preservada entre stages paralelas
- Canais sem buffer fornecem contrapressão
Perguntas Frequentes
A aula “Fan-out e fan-in” é grátis?
Sim — o texto completo de “Fan-out e fan-in” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Go Academy, atualize para CoddyKit PRO. O curso de Go Academy inclui 4 aulas no total.
O que vou aprender em “Fan-out e fan-in”?
Distribua e reúna o trabalho Você pratica Go Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Go Academy?
Nenhuma experiência prévia é necessária. Go Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Fan-out e fan-in”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Go Academy?
Sim. Cada aula de Go Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.