package main import ( "fmt" "time" "sync" ) type payloadData struct { Index int } type resultData struct { Res int } type job struct { Payload payloadData Result chan resultData } func worker(jobs <-chan job) { for { // get next job params := <-jobs fmt.Printf("-> index: %d\n", params.Payload.Index) // simulate a heavy processing time.Sleep(1 * time.Second) // return result params.Result <- resultData{Res: params.Payload.Index} } } var jobPool chan job func main() { workerCount := 5 jobPool = make(chan job) // start a fixed amount of workers for i := 0; i < workerCount; i++ { go worker(jobPool) } // needed only to wait until all go routines will complete var wg sync.WaitGroup for j := 0; j < 10; j++ { wg.Add(1) go func(i int){ defer wg.Done() // prepare channel for result c := make(chan resultData) // send job to worker jobPool <- job{Payload: payloadData{Index: i}, Result: c} // wait till complete data := <-c fmt.Printf("<- result: %d\n", data.Res); }(j) } wg.Wait() }