利用协程顺序输出"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一直在等待,从而导致报错。

原文地址:https://www.cnblogs.com/hzpeng/p/15415402.html