毋庸置疑,协程(goroutine)与通道(channel)绝对是golang最强的两个特性,也是它们造就了golang强大的异步与并发能力

可能有小伙伴遇到过下面这种情况:

开启了5个协程,阻塞一秒后输出变量i,但运行后发现程序瞬间结束,没有得到预期的输出

这是因为goroutine还没开始,主进程就已经结束了的原因

这时可以通过两个办法解决,下面来说


配合Channel等待goroutine结束

原理很简单,创建一个通道,当协程执行完毕时,传输一个值至通道,主进程处只需等待一定数量的值从通道拿出后,再结束程序即可


goroutine配合channel,很轻松的就能实现生产者-消费者模式:

结果是这样的:

还有一种替代方法,那就是利用sync.WaitGroup


WaitGroup

sync.WaitGroup是用于等待多个goroutine结束的:

结构体只有三个方法:

  • Add方法,通知当前需等待结束的goroutine数量

  • Done方法用于goroutine中,当其结束后调用,使等待的数量减1

  • Wait方法用于阻塞,当数量为0时,结束阻塞

等待10个goroutine结束,wg是外部变量

WaitGroup有一个误区,在它的结构体文档上也标明了:

A WaitGroup must not be copied after first use.

WaitGroup第一次使用后,就不能够再次复制

也就是说,将上面的例子换成下面这样是错误的:

错误的例子

值传递存在复制的行为,所以只能传递它的指针:

正确的姿势





thanks for reading~