• 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()
    }
    
  • 相关阅读:
    14.4.2 Change Buffer 延迟写
    14.4.1 Buffer Pool
    如何围绕业务特性,做企业信息化?
    如何围绕业务特性,做企业信息化?
    14.3 InnoDB Multi-Versioning InnoDB 多版本
    14.2 InnoDB and the ACID Model
    14.1.3 检查InnoDB 可用性:
    14.1.2 InnoDB表最佳实践:
    14.1.1 使用InnoDB 表的好处:
    7.5.1 Point-in-Time Recovery Using Event Times 使用Event Times 基于时间点恢复
  • 原文地址:https://www.cnblogs.com/linyihai/p/10285437.html
Copyright © 2020-2023  润新知