利用协程顺序输出"xxx",sync.WaitGroup使用注意!
顺序输出123
// 实现顺序输出123
func TestPrintNum(t *testing.T) {
w := sync.WaitGroup{}
a := make(chan struct{},1)
b := make(chan struct{})
w.Add(2)
go func() {
defer w.Done()
for i:=1;i<4;i++{
<-a
if i % 2 != 0 {
fmt.Println(i)
}
b <- struct{}{}
}
}()
go func() {
defer w.Done()
for i:=1;i<4;i++{
<-b
if i % 2 == 0 {
fmt.Println(i)
}
a <- struct{}{}
}
}()
a <- struct{}{}
w.Wait()
}
顺序输出dog、cat、fish
// 三个协程顺序输出 dog、cat、fish 四次
func TestDogCatAndFish(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(3)
dog := make(chan struct{},1)
cat := make(chan struct{})
fish := make(chan struct{})
dog <- struct{}{}
go PrintDog(&wg,dog,cat)
go PrintCat(&wg,cat,fish)
go PrintFish(&wg,fish,dog)
wg.Wait()
}
func PrintDog(wg *sync.WaitGroup,dog,cat chan struct{}) {
defer wg.Done()
for i := 0;i < 4;i++ {
<- dog
fmt.Println("dog")
cat <- struct{}{}
}
}
func PrintCat(wg *sync.WaitGroup,cat,fish chan struct{}) {
defer wg.Done()
for i := 0;i < 4;i++ {
<- cat
fmt.Println("cat")
fish <- struct{}{}
}
}
func PrintFish(wg *sync.WaitGroup,fish,dog chan struct{}) {
defer wg.Done()
for i := 0;i < 4;i++ {
<- fish
fmt.Println("fish")
dog <- struct{}{}
}
}
sync.WaitGroup使用注意
在上面的顺序输出dog、cat、fish的例子中,将wg变量通过函数参数的方式传递到函数当中,一定注意需要传递指针类型!
因为在golang中如果传递的不是地址,则会进行值拷贝传递,导致在函数中调用的不是同一个对象,而主方法中的wg一直在等待,从而导致报错。