go实现N个goroutine交替打印数字 - Go语言中文社区

go实现N个goroutine交替打印数字


go中CSP模型提倡“不要以共享内存的方式来通信,相反,要以通信来共享内存”,go的CSP模型,就是通过goroutine和channel结合的形式来实现的。

这里通过goroutine和channel实现了一个简单的并发控制,即通过channel在不同的goroutine之间传递信息,而不是通过锁的形式,或者是共享变量的形式来实现。

例如要实现3个goroutine交替输出1-30的数字,可以参考下面的实现方法:

下方会有解释


func getWorker(waitCh chan int, symbol int, wg *sync.WaitGroup) (next chan int) {
	notify := make(chan int)
	wg.Add(1)
	go func(waitCh chan int) {
		defer func() {
			wg.Done()
		}()
		for d := range waitCh {
			if d >= 30 {
				break
			}
			fmt.Println("goroutine:", symbol, "print", d+1)
			notify <- d + 1
		}
		close(notify)
		fmt.Println("goroutine: finish", symbol)
	}(waitCh)
	return notify
}

func main() {
	wg := new(sync.WaitGroup)
	start := make(chan int)
	lastCh := start
	for i := 0; i < 3; i++ {
		lastCh = getWorker(lastCh, i+1, wg)
	}
	start<-0
	for v := range lastCh {
		start<-v
	}
	close(start)
	wg.Wait()
}
  • 每次创建goroutine时,waitCh是该协程等待信号的channel,当这个goroutine完成任务时,发信号到notify channel中。
  • waitGroup的目的是为了主协程等待所有goroutine都结束后再结束,即优雅的停止。
  • goroutine执行完任务后,将notify channel关闭。

这样,我们在main函数中先创建一个start channel,然后循环创建goroutine,每次创建的goroutine的waitCh为上次创建goroutine返回的notify channel,循环结束后,我们在main函数中将最后一个channel的内容发到start channel中,这样,就构成了一个环。

最后,我们往start channel中发一个信号,goroutine环中就会交替打印数字啦,等到结束条件满足后,某个notifyCh被close,也会使得整个goroutine环都循环被关闭,最终优雅的结束。

 

下方是3个goroutine交替打印1-10的运行结果:

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/liyunlong41/article/details/108999918
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-21 20:51:27
  • 阅读 ( 1982 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢