0
点赞
收藏
分享

微信扫一扫

Go协程同步的几种方式

Go协程同步的几种方式_协程

为什么要有协程同步?


​func main() {​

​go func() {​

​fmt.Println(​​​​"goroutine 1"​​​​)​

​}()​

​go func() {​

​fmt.Println(​​​​"goroutine 2"​​​​)​

​}()​

​}​


执行以上代码块,发现没有打印结果,原因就是主协程main在goroutine 1和goroutine 2执行之前已经先行结束,协程没有同步。

1.让主协程休息一段时间,等待其他协程执行完成后再结束


​func main() {​

​go func() {​

​fmt.Println(​​​​"goroutine 1"​​​​)​

​}()​

​go func() {​

​fmt.Println(​​​​"goroutine 2"​​​​)​

​}()​

​time.Sleep(time.Second)​

​}​


缺点是不知道需要等待多长时间

2.channel


​func main() {​

​ch := make(chan struct{})​

​go func() {​

​fmt.Println(​​​​"goroutine 1"​​​​)​

​ch <- struct{}{}​

​}()​

​go func() {​

​fmt.Println(​​​​"goroutine 2"​​​​)​

​ch <- struct{}{}​

​}()​

​<-ch​

​<-ch​

​}​


channel和goroutine是分不开的,搭配干活不累。

3.sync.WaitGroup

  • Add() 用来添加计数
  • Done() 用来在操作结束时调用,使计数减一
  • Wait() 用来等待所有的操作结束,即计数变为 0,该函数会在计数不为 0 时等待,在计数为 0 时立即返回


​func main() {​

​var wg sync.WaitGroup​

​wg.Add(​​​​2​​​​)​

​go func() {​

​fmt.Println(​​​​"goroutine 1"​​​​)​

​wg.Done()​

​}()​

​go func() {​

​fmt.Println(​​​​"goroutine 2"​​​​)​

​wg.Done()​

​}()​

​wg.Wait()​

​}​


关于WaitGroup源码如下:


​// A WaitGroup waits for a collection of goroutines to finish.​

​// The main goroutine calls Add to set the number of​

​// goroutines to wait for. Then each of the goroutines​

​// runs and calls Done when finished. At the same time,​

​// Wait can be used to block until all goroutines have finished.​

​//​

​// A WaitGroup must not be copied after first use.​

​type WaitGroup struct {​

​noCopy noCopy​


​// 64-bit value: high 32 bits are counter, low 32 bits are waiter count.​

​// 64-bit atomic operations require 64-bit alignment, but 32-bit​

​// compilers do not ensure it. So we allocate 12 bytes and then use​

​// the aligned 8 bytes in them as state, and the other 4 as storage​

​// for the sema.​

​state1 [​​​​3​​​​]uint32​

​}​


一个WaitGroup等待多个goroutine执行完成,main的goroutine可以调用Add()方法设置需要等待的goroutine数量,之后每一个goroutine在运行结束时调用Done(),在这段时间内,我们可以使用Wait()阻塞main的goroutine直到所有的goroutine都执行完成,WaitGroup不能进行复制操作【struct里面有noCopy类型,禁止做值拷贝,只能通过指针来传递】

Go协程同步的几种方式_sed_02


举报

相关推荐

0 条评论