0Pricing
Go Academy · Aula

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.

Todas as aulas deste curso

  1. Padrão de pool de trabalhadores
  2. Fan-out e fan-in
  3. Estágios do pipeline
  4. Desligamento normal
← Voltar para Go Academy