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 {
|
2019-05-10 10:11:04 +03:00
|
|
|
waitCh chan struct{}
|
|
|
|
sign chan struct{}
|
2019-05-06 11:00:16 +03:00
|
|
|
}
|
|
|
|
|
2019-05-10 09:57:25 +03:00
|
|
|
func NewChanBarrier(gos int)*ChanBarrier{
|
2019-05-10 10:11:04 +03:00
|
|
|
b := &ChanBarrier{
|
|
|
|
waitCh:make(chan struct{} ,gos-1),
|
|
|
|
sign:make(chan struct{}),
|
2019-05-06 11:00:16 +03:00
|
|
|
}
|
2019-05-10 10:11:04 +03:00
|
|
|
for i:=0;i<gos-1;i++{
|
|
|
|
b.waitCh <- struct{}{}
|
|
|
|
}
|
|
|
|
return b
|
2019-05-06 11:00:16 +03:00
|
|
|
}
|
|
|
|
|
2019-05-10 10:11:04 +03:00
|
|
|
func (b *ChanBarrier) Await() error {
|
|
|
|
select {
|
|
|
|
case <- b.waitCh:
|
|
|
|
<- b.sign
|
|
|
|
default:
|
|
|
|
close(b.sign)
|
|
|
|
close(b.waitCh)
|
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++ {
|
2019-05-10 10:11:04 +03:00
|
|
|
go func(n int) {
|
|
|
|
log.Println(n ,"await")
|
2019-05-06 11:00:16 +03:00
|
|
|
if err := b.Await();err != nil{
|
|
|
|
log.Println(err)
|
|
|
|
}
|
2019-05-10 10:11:04 +03:00
|
|
|
log.Println(n ,"pass")
|
2019-05-06 11:00:16 +03:00
|
|
|
wg.Done()
|
2019-05-10 10:11:04 +03:00
|
|
|
}(i)
|
2019-05-06 11:00:16 +03:00
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
}
|
|
|
|
|