乐趣区

关于golang:谈谈Golang的同步等待组

作者:ReganYue

起源:恒生 LIGHT 云社区

大家好,这里是致力变得优良的 R 君,这次咱们持续来进行 Golang 系列《让咱们一起 Golang》,区块链系列内容明年会持续更新,共识算法曾经根本结束,如果不出意外,除夕那个星期就是介绍如何构建公链我的项目了,本次咱们来理解 Golang 的同步期待组,这也是一个比拟容易了解的知识点,咱们来看一看吧!

咱们当初开十条子协程,而后当十条子协程全副完结后,主协程立马完结。动动你的小脑袋,想一想应该怎么做?如果是一条子协程的话就很容易实现,当这条子协程完结时让主协程完结就行了。然而咱们当初是 10 条,让任何一条子协程公布让主协程完结的命令都不行,因为你无奈确定哪一条子协程是最初完结的。所以咱们当初用上了期待组。

期待组是什么原理呢?发明一个子协程就注销一下,而后子协程干完活就将其除名,名单除洁净了就完结主协程。

咱们来看看期待组的无关示例:

func main() {fmt.Println(time.Now())
    var wg sync.WaitGroup
    // 起一个协程就加一
    wg.Add(1)
    go func() {
        for i:=0;i<5;i++{fmt.Println(i)
            // 相当于阻塞一秒,读到工夫
            <- time.After(time.Second)
        }
        fmt.Println(time.Now())
        // 活干完之后减一
        wg.Done()}()

    wg.Add(1)
    go func() {
        var i int
        ticker := time.NewTicker(time.Second)
        for{
            <- ticker.C
            i++
            fmt.Println("秒表",i)
            if i>9 {break}
        }
        fmt.Println(time.Now())
        wg.Done()}()
    // 期待组阻塞期待至记录清零为止
    wg.Wait()
    fmt.Println("END")
}

这段代码是建设一条协程就应用 wg.Add(1)给期待组加一,而后活干完之后就减一。

WaitGroup 期待一组 goroutine 实现。主 goroutine 调用 Add 来增加要期待的 goroutine 的数量。而后每个 goroutine 运行并在实现时调用 Done。同时,Wait 可用于阻塞,直到所有 goroutine 实现。

Add()办法是用来设置期待组中的计数器的值,咱们能够了解每个期待组中都有一个计数器,这个计数器能够用来示意这个期待组中要执行的协程数量。如果计数器为零,那么示意被阻塞的协程都被开释了。

Done()办法就是当同步期待组中的某个协程执行结束后,使同步期待组中的计数器数量减一。

这里一条协程 5 秒完结,另一条协程 10 秒完结,那按理来说应该是 10 秒完结,咱们来看看运行后果吧!

2021-08-25 19:10:28.3511953 +0800 CST m=+0.016989401
0
1
秒表 1
2
秒表 2
秒表 3
3
秒表 4
4
秒表 5
2021-08-25 19:10:33.4452142 +0800 CST m=+5.111008301
秒表 6
秒表 7
秒表 8
秒表 9
秒表 10
2021-08-25 19:10:38.4369656 +0800 CST m=+10.102759701
END

上面来谈谈几个须要留神的事项:

  1. 咱们应用期待组时不能够在 wg.Add()中填入正数,不然会导致报错。报错后果如下:panic: sync: negative WaitGroup counter这点须要留神。
  2. WaitGroup 对象不是一个援用类型 在通过函数传值时须要应用地址,须要通过指针传值,不然程序会呈现死锁!

想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?

恒生 LIGHT 云社区,由恒生电子搭建的金融科技业余社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。

扫描下方小程序二维码,退出咱们!

退出移动版