Skip to content

Instantly share code, notes, and snippets.

@zucchinidev
Created October 5, 2017 13:34
Show Gist options
  • Save zucchinidev/f2dc8875fb78c2bfc7f4b4bb2dc96a01 to your computer and use it in GitHub Desktop.
Save zucchinidev/f2dc8875fb78c2bfc7f4b4bb2dc96a01 to your computer and use it in GitHub Desktop.
The purpose of the work package is to show how you can use an unbuffered channel to create a pool of goroutines that will perform and control the amount of work that gets done concurrently
package main
import (
"log"
"github.com/zucchinidev/work/work"
"sync"
"time"
)
var names = []string{
"steve",
"bob",
"mary",
"therese",
"jason",
}
const tasks = 10000
type namePrinter struct {
name string
}
func (printer *namePrinter) Task() {
log.Println(printer.name)
time.Sleep(time.Millisecond * 100)
}
func main() {
pool := work.New(1000)
var wg sync.WaitGroup
wg.Add(tasks * len(names))
for i := 0; i < tasks; i++ {
for _, name := range names {
printer := namePrinter{
name: name,
}
go func() {
pool.Run(&printer)
wg.Done()
}()
}
}
wg.Wait()
pool.Shutdown()
}
package work
import (
"sync"
)
// Package work manaages a pool of goroutines to perform work.
type Worker interface {
Task()
}
type Pool struct {
work chan Worker
waitGroup sync.WaitGroup
}
func New(maxNumWorkers int) *Pool {
pool := Pool{
work: make(chan Worker),
}
pool.waitGroup.Add(maxNumWorkers)
for i := 0; i < maxNumWorkers; i++ {
go func() {
for work := range pool.work {
work.Task()
}
pool.waitGroup.Done()
}()
}
return &pool
}
func (pool *Pool) Run(worker Worker) {
pool.work <- worker
}
func (pool *Pool) Shutdown() {
close(pool.work)
pool.waitGroup.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment