2019-05-06 11:00:16 +03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
type IBarrier interface {
|
2019-05-10 09:57:25 +03:00
|
|
|
// error for timeout if need
|
2019-05-06 11:00:16 +03:00
|
|
|
Await() error
|
|
|
|
}
|
|
|
|
|
2019-05-10 09:57:25 +03:00
|
|
|
|
|
|
|
// once
|
|
|
|
type ChanBarrier struct {
|
|
|
|
gos int
|
|
|
|
curGos int
|
|
|
|
ch chan struct{}
|
|
|
|
m sync.Mutex
|
2019-05-06 11:00:16 +03:00
|
|
|
}
|
|
|
|
|
2019-05-10 09:57:25 +03:00
|
|
|
func NewChanBarrier(gos int)*ChanBarrier{
|
|
|
|
return &ChanBarrier{
|
|
|
|
gos:gos,
|
|
|
|
ch:make(chan struct{}),
|
2019-05-06 11:00:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 09:57:25 +03:00
|
|
|
func (c *ChanBarrier) Await() error {
|
|
|
|
c.m.Lock()
|
|
|
|
if c.curGos++;c.gos != c.curGos{
|
|
|
|
c.m.Unlock()
|
|
|
|
<- c.ch
|
2019-05-06 11:00:16 +03:00
|
|
|
}else{
|
2019-05-10 09:57:25 +03:00
|
|
|
c.m.Unlock()
|
|
|
|
close(c.ch)
|
2019-05-06 11:00:16 +03:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-05-10 09:57:25 +03:00
|
|
|
//type Barrier struct {
|
|
|
|
// cond *sync.Cond
|
|
|
|
// gos uint
|
|
|
|
// curgos uint
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
//func NewBarrier(syncGos uint)*Barrier{
|
|
|
|
// if syncGos < 1{
|
|
|
|
// panic("min 1")
|
|
|
|
// }
|
|
|
|
// l := &sync.Mutex{}
|
|
|
|
// c := sync.NewCond(l)
|
|
|
|
// return &Barrier{
|
|
|
|
// cond:c,
|
|
|
|
// gos:syncGos,
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
//func (b *Barrier)Await() error{
|
|
|
|
// b.cond.L.Lock()
|
|
|
|
// defer b.cond.L.Unlock()
|
|
|
|
// b.curgos++
|
|
|
|
// if b.gos != b.curgos{
|
|
|
|
// b.cond.Wait()
|
|
|
|
// }else{
|
|
|
|
// b.curgos = 0
|
|
|
|
// b.cond.Broadcast()
|
|
|
|
// }
|
|
|
|
// return nil
|
|
|
|
//}
|
|
|
|
|
2019-05-06 11:00:16 +03:00
|
|
|
|
|
|
|
|
|
|
|
func main(){
|
|
|
|
var b IBarrier
|
|
|
|
wg := &sync.WaitGroup{}
|
|
|
|
gos := 10
|
|
|
|
wg.Add(gos)
|
2019-05-10 09:57:25 +03:00
|
|
|
//b = NewBarrier(uint(gos))
|
|
|
|
b = NewChanBarrier(gos)
|
2019-05-06 11:00:16 +03:00
|
|
|
for i:=0;i<gos ;i++ {
|
|
|
|
go func() {
|
|
|
|
log.Println("await")
|
|
|
|
if err := b.Await();err != nil{
|
|
|
|
log.Println(err)
|
|
|
|
}
|
|
|
|
log.Println("pass")
|
|
|
|
wg.Done()
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
}
|
|
|
|
|