Skip to content

Instantly share code, notes, and snippets.

@urey-hiker
Last active March 1, 2018 10:04
Show Gist options
  • Save urey-hiker/df7aa0664dd126c87d3f5e4e7a27d29a to your computer and use it in GitHub Desktop.
Save urey-hiker/df7aa0664dd126c87d3f5e4e7a27d29a to your computer and use it in GitHub Desktop.
Barrier for concurrency workers to do tasks synchronously.
package main
import "sync"
type barrier struct {
wc int
c chan int
wg sync.WaitGroup
sync.Mutex
}
func (br *barrier) fence(w int) {
id := 0
br.wg.Wait()
br.Lock()
br.wc++
id = br.wc
if id == 1 {
br.c = make(chan int)
}
if id == w {
br.wg.Add(1)
close(br.c)
}
br.Unlock()
<-br.c
if id == w {
br.wc = 0
br.wg.Done()
}
}
@urey-hiker
Copy link
Author

Inspired by this article to create barriers for concurrency workers.

The barrier can block workers until all of them ran into br.fence(w).
br.fence can be used multi-times in one worker loop to synchronous several steps, like this:

func worker(c *counter, w int, br *barrier, wg *sync.WaitGroup) {
	for i := 0; i < 3; i++ {
		// wait for all workers to finish previous loop
		br.fence(w)
		c.Incr()
		// wait for other workers to do bootstrap
		br.fence(w)
		time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
		fmt.Println(c.Get())
	}
	wg.Done()
}

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