package main
import (
"fmt"
"sync"
)
type Lock struct {
ch chan struct{}
}
func NewLock() *Lock {
return &Lock{
ch: make(chan struct{}, 1),
}
}
func (t *Lock) Lock() {
<-t.ch
}
func (t *Lock) Unlock() {
t.ch <- struct{}{}
}
type Barrier struct {
max int
cur int
cha chan int
lock *Lock
}
func NewBarrier(count int) *Barrier {
channel := make(chan int)
lock := NewLock()
return &Barrier{max: count,cur: count,cha: channel,lock: lock}
}
func (barrier *Barrier) decrease() {
barrier.lock.Lock()
barrier.cur--
defer barrier.lock.Unlock()
}
func (barrier *Barrier) reset() {
barrier.lock.Lock()
barrier.cur=barrier.max
defer barrier.lock.Unlock()
}
func (barrier *Barrier) read() int{
barrier.lock.Lock()
defer barrier.lock.Unlock()
return barrier.cur
}
func (barrier *Barrier) Wait() {
barrier.lock.Lock()
if barrier.cur--; barrier.cur > 0 {
barrier.lock.Unlock()
<-barrier.cha
} else {
for i:=0;i<barrier.max-1;i++{
barrier.cha<-1
}
barrier.cur=barrier.max
barrier.lock.Unlock()
}
}
func main() {
barrier := NewBarrier(100)
var wg sync.WaitGroup
barrier.lock.Unlock()
for i:=0;i<100;i++ {
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("1")
barrier.Wait()
fmt.Println("2")
barrier.Wait()
fmt.Println("3")
}()
}
wg.Wait()
}