Code Snippets
/

Goroutine + Channel Fan-Out

Goroutine + Channel Fan-Out

Fan-out is the canonical Go concurrency pattern: a producer pushes jobs onto a channel, a fixed pool of worker goroutines pulls and processes them in parallel, and results flow back through a results channel. This snippet shows a minimal worker pool, the close + range idiom that signals completion, and a `sync.WaitGroup` variant for fire-and-forget. Use this whenever you need parallelism with a bounded number of workers.

Go
Medium
3 snippets
go-goroutines
go-channels
go-concurrency-patterns
concurrency

857 views

15

package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        time.Sleep(20 * time.Millisecond) // pretend work
        results <- j * j
        _ = id
    }
}

func main() {
    const numWorkers = 3
    jobs := make(chan int, 10)
    results := make(chan int, 10)

    var wg sync.WaitGroup
    for w := 1; w <= numWorkers; w++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            worker(id, jobs, results)
        }(w)
    }

    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs) // signals workers to exit their range loops.

    go func() { wg.Wait(); close(results) }()

    sum := 0
    for r := range results {
        sum += r
    }
    fmt.Println("sum of squares =", sum)
}

Two channels carry direction: jobs flows producer to workers, results flows workers to consumer. The worker uses for j := range jobs which exits cleanly when jobs is closed; that is what the close(jobs) after the producer loop does. A sync.WaitGroup tracks how many worker goroutines are still running so the consumer can close results only when all workers have finished. The buffered channels (make(chan int, 10)) decouple producer and consumer enough to overlap, but pick the buffer size based on actual workload, not by reflex. The whole pattern is O(jobs / workers) wall time at the cost of one goroutine per worker plus two channels.