Skip to content

Instantly share code, notes, and snippets.

@sylr
Created February 11, 2020 09:49
Show Gist options
  • Select an option

  • Save sylr/b065e1fbd3de0c2ff095d83b969e6db4 to your computer and use it in GitHub Desktop.

Select an option

Save sylr/b065e1fbd3de0c2ff095d83b969e6db4 to your computer and use it in GitHub Desktop.
wg.go
package main
// Original code found at: https://play.golang.org/p/kWmjEuXn0ab
import (
"fmt"
"sync"
"time"
)
func main() {
g := newGroup(3)
for i := 0; i < 10; i++ {
g.Add(1)
go func(i int) {
time.Sleep(1 * time.Second)
fmt.Println(i)
g.Done()
}(i)
}
g.Wait()
fmt.Println("done")
}
type group struct {
mtx sync.Mutex
cnd *sync.Cond
max int
cur int
}
func newGroup(max int) *group {
g := &group{
max: max,
}
g.cnd = sync.NewCond(&g.mtx)
return g
}
func (g *group) Add(n int) {
g.mtx.Lock()
defer g.mtx.Unlock()
for (g.cur + n) > g.max {
g.cnd.Wait()
}
g.cur += n
}
func (g *group) Done() {
g.mtx.Lock()
defer g.mtx.Unlock()
g.cur--
if g.cur < 0 {
panic("improper use of group")
}
g.cnd.Broadcast()
}
func (g *group) Wait() {
g.mtx.Lock()
defer g.mtx.Unlock()
for g.cur > 0 {
g.cnd.Wait()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment