Skip to content

Instantly share code, notes, and snippets.

@kumikoda
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kumikoda/731ea620d0f32050c479 to your computer and use it in GitHub Desktop.
Save kumikoda/731ea620d0f32050c479 to your computer and use it in GitHub Desktop.
Using go routines and channels to do some work
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// create the channel that all workers will listen on
tasks := make(chan string, 64)
// create a pool of workers
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
// increment wait group
wg.Add(1)
// start the worker
// the tasks channel allows it to recieve work
// the wait group allows it to declare done
go worker(tasks, &wg)
}
// fill our task queue with some work
// if the channel is full, this will block
// and continue when its no longer full
test_ids := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}
for _, id := range test_ids {
tasks <- id
}
// when all tasks have been sent out, we close this channel
// idle works will then quit
close(tasks)
// wait for all workers to quit
wg.Wait()
fmt.Println("main done")
}
func worker(tasks <-chan string, wg *sync.WaitGroup) {
// decrement wait group when worker exits
defer wg.Done()
// wait for tasks indefinitely
for {
task, ok := <-tasks
// not ok means channel has been closed
if !ok {
fmt.Println("worker done")
return
}
// take a task off the channel and work
time.Sleep(time.Second)
fmt.Println(task)
}
}
@eculver
Copy link

eculver commented Aug 7, 2015

I think it's more "idomatic" if you keep the main() as readable and straightforward as possible. So, instead of doing the for loop in main, you're probably better off breaking it out into its own function. In practice, the main function gets abused and can become unwieldy pretty easily.

Other than that, I think this is a pretty solid approach to worker pool/fan-out. It's a pretty popular topic. If you haven't already looked around, I found this thread insightful:

http://stackoverflow.com/questions/23837368/idiomatic-variable-size-worker-pool-in-go

And this example:

http://play.golang.org/p/VlEirPRk8V

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment