sync.WaitGroup和sync.Once

Posted linyihai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sync.WaitGroup和sync.Once相关的知识,希望对你有一定的参考价值。

sync.WaitGroup,顾名思义,等待一组goroutinue运行完毕。sync.WaitGroup声明后即可使用,它有如下方法:

  1. func (wg *WaitGroup) Add(delta int) #不能传入符数,否则引发panic
  2. func (wg *WaitGroup) Done()
  3. func (wg *WaitGroup) Wait()

    一般套路是,"先统一Add, 在并发Done, 最后Wait"。中心思想是由一个goroutine或主程序来调用Add和Wait方法,其他goroutinue作为子任务调用done方法,否则会引发可能的panic异常。

sync.Once, 也是开箱即用的,声明后即可使用,只有一个方法:

  1. func (o *Once) Do(f func())

sync.Once需要注意以下两点,避免踩坑:

  1. 当多个goroutinue并发地调用同一个sync.Once实例时,如果传入的函数执行时间过长,由于sync.Once是使用锁机制,保证传入的函数只执行一次,因此会造成其他goroutinue函数的阻塞。
  2. sync.Once 有一个done的unint32的字段,取值只有0和1。只要Do方法执行完成,done就由0变为1。值得注意的是done由defer保证执行后一定会是1。
package main
import "sync"
import "fmt"
import "sync/atomic"
import "time"

const PI = 3.14
var w sync.WaitGroup
var once sync.Once
var doneTaskCount int32

func calCircleCircum(r float64, ret *float64) {
  defer w.Done()
  *ret = PI * r
  atomic.AddInt32(&doneTaskCount, 1)
  time.Sleep(time.Millisecond * 2000)
}

func calRectangleCircum(width float64, long float64, ret *float64) {
  defer w.Done()
  *ret = 2 * (long + width)
  atomic.AddInt32(&doneTaskCount, 1)
  time.Sleep(time.Millisecond * 1000)
}

func printResults(circleRet *float64, rectangleRet *float64) {
  
  once.Do(func(){
    for atomic.LoadInt32(&doneTaskCount) !=2 {
      fmt.Println("Wait sub task done.....")
      time.Sleep(time.Millisecond * 200)
    }
  })


  fmt.Printf("the cicle circumference is %1.2f
", *circleRet)
  fmt.Printf("the rectangle circumference is %1.2f
", *rectangleRet)
}

func main() {
  circleRet := 0.0
  rectangleRet := 0.0
  
  w.Add(2)
  go printResults(&circleRet, &rectangleRet)
  go calCircleCircum(2.0, &circleRet)
  go calRectangleCircum(2.0, 3.0, &rectangleRet)
  w.Wait()
}

以上是关于sync.WaitGroup和sync.Once的主要内容,如果未能解决你的问题,请参考以下文章

Go语言开发(十三)Go语言常用标准库三

Go语言基础-sync包

Golang sync.WaitGroup

Golang的sync.WaitGroup 实现逻辑和源码解析

Go sync.WaitGroup的学习

go语言学习笔记 — 进阶 — 并发编程(11):同步sync,等待组(sync.WaitGroup)—— 保证在并发环境中完成指定数量的任务