A simple worker pool implementation:
package main
import (
"fmt"
"sync"
)
type job struct {
// some fields for your job type
}
type result struct {
// some fields for your result type
}
func worker(jobs <-chan job, results chan<- result) {
for j := range jobs {
var r result
// do some work
results <- r
}
}
func main() {
// make our channels for communicating work and results
jobs := make(chan job, 100) // 100 was chosen arbitrarily
results := make(chan result, 100)
// spin up workers and use a sync.WaitGroup to indicate completion
wg := sync.WaitGroup
for i := 0; i < runtime.NumCPU; i++ {
wg.Add(1)
go func() {
defer wg.Done()
worker(jobs, results)
}()
}
// wait on the workers to finish and close the result channel
// to signal downstream that all work is done
go func() {
defer close(results)
wg.Wait()
}()
// start sending jobs
go func() {
defer close(jobs)
for {
jobs <- getJob() // I haven't defined getJob() and noMoreJobs()
if noMoreJobs() { // they are just for illustration
break
}
}
}()
// read all the results
for r := range results {
fmt.Println(r)
}
}