面试官:实现协程同步有哪些方式?( 二 )

打印输出:
大妈做第 1 个面包大叔吃了第 1 个面包大妈做第 2 个面包大叔吃了第 2 个面包大妈做第 3 个面包大叔吃了第 3 个面包大妈做第 4 个面包大叔吃了第 4 个面包大妈做第 5 个面包大叔吃了第 5 个面包没面包了 , 大叔也饱了fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan receive]:main.consumer(0xc00008c060, 0x0) /data1/htdocs/go_project/src/github.com/cnyygj/go_practice/test.go:19 +0x5fmain.main() /data1/htdocs/go_project/src/github.com/cnyygj/go_practice/test.go:32 +0x7cexit status 2果然阻塞掉了 , 最终形成了死锁 , 抛出异常了 。
sync.WaitGroup【面试官:实现协程同步有哪些方式?】如果你觉的上面两种方法还不过瘾 , 接下来我们再看个方法:sync.WaitGroup
WaitGroup 内部实现了一个计数器 , 用来记录未完成的操作个数 , 它提供了三个方法:

  • Add() 用来添加计数
  • Done() 用来在操作结束时调用 , 使计数减一 【我不会告诉你 Done() 方法的实现其实就是调用 Add(-1)】
  • Wait() 用来等待所有的操作结束 , 即计数变为 0 , 该函数会在计数不为 0 时等待 , 在计数为 0 时立即返回
还是看栗子:
func main(){var wg sync.WaitGroupwg.Add(2) // 因为有两个动作 , 所以增加2个计数go func() {fmt.Println("Goroutine 1")wg.Done() // 操作完成 , 减少一个计数}()go func() {fmt.Println("Goroutine 2")wg.Done() // 操作完成 , 减少一个计数}()wg.Wait() // 等待 , 直到计数为0}打印输出:
Goroutine 1Goroutine 2以上就是今天要跟大家分享的内容 , 欢迎留言交流~
面试官:实现协程同步有哪些方式?文章插图