// Created on savesnippets.com ยท https://savesnippets.com/h9SatI1G3GV56y package main import ( "fmt" "sync" ) func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) { defer wg.Done() for j := range jobs { results <- j * j // pretend this is expensive _ = id } } func main() { const numJobs = 20 const numWorkers = 4 jobs := make(chan int, numJobs) results := make(chan int, numJobs) var wg sync.WaitGroup for w := 1; w <= numWorkers; w++ { wg.Add(1) go worker(w, jobs, results, &wg) } // Send all jobs for j := 1; j <= numJobs; j++ { jobs <- j } close(jobs) // tells workers "no more" // Wait for workers in a separate goroutine, then close results go func() { wg.Wait(); close(results) }() for r := range results { fmt.Println(r) } }