Go 语言入门很简单:WaitGroup

举报
宇宙之一粟 发表于 2022/10/31 19:33:10 2022/10/31
【摘要】 Fork-Join 模型在并发中,Fork-Join 模型是一种设置和执行并发程序的方式,使得执行在指定点处分支,并在后续点处加入或合并,并恢复顺序执行。 Fork 一词指的是程序运行时的任何时间点,它可以创建一个或多个子执行分支,以同时运行或在某些情况下与父级并行运行。 Join 一词指的是将来并发执行分支连接回父级的时间点。WaitGroups现在,我们对并发模型 Fork-Join 有...



Fork-Join 模型

在并发中,Fork-Join 模型是一种设置和执行并发程序的方式,使得执行在指定点处分支,并在后续点处加入或合并,并恢复顺序执行。 Fork 一词指的是程序运行时的任何时间点,它可以创建一个或多个子执行分支,以同时运行或在某些情况下与父级并行运行。 Join 一词指的是将来并发执行分支连接回父级的时间点。



WaitGroups

现在,我们对并发模型 Fork-Join 有了更多的了解。看一段代码:

package main

import "fmt"

func sayGreetings() {
    fmt.Println("Hello World!!")
}

func main() {
    go sayGreetings()
}

当我们运行上面的代码时,会有两种可能。首先,sayGreetings 协程打印 Hello World!并在主 goroutine 之前完成它的执行。在这种情况下,Fork 和 Join 操作都会发生。在第二种情况下,sayGreetings goroutine 将无法在 main goroutine 之前完成其执行。在这种情况下,Join 操作将不会发生。




为了解决上述问题,我们需要确保 Join 操作在所有情况下都发生在主 goroutine 完成执行之前。我们可以使用 Go 内置库的 sync 包提供的同步原语 WaitGroup。

WaitGroup 等待一组 goroutine 完成。我们可以将 WaitGroup 视为并发安全计数器。 WaitGroup 提供了三个附加的方法。

type WaitGroup

    func (wg *WaitGroup) Add(delta int)
    func (wg *WaitGroup) Done()
    func (wg *WaitGroup) Wait()
  • ​func (wg *WaitGroup) Add(delta int)​​  方法将计数器增加传入的整数。传入 Add 方法的整数表示创建的新 goroutine 的数量。
  • ​func (wg *WaitGroup) Done()​​  方法将计数器减一。当 goroutine 完成执行时,我们调用 Done 方法。
  • ​func (wg *WaitGroup) Wait()​​  方法用于阻塞执行,直到所有部署的 goroutine 都已完成执行。

使用 ​​sync.WaitGroup​​​  我们可以避免使用 ​​time.Sleep​​​  来等待我们的 goroutines 完成。 相反,我们创建一个 ​​sync.WaitGroup​​​  并为我们希望启动的每个 goroutine 将其计数器加 1。 然后,在每个 goroutine 中,我们递减计数器。 最后我们调用 WaitGroup 上的 ​​Wait()​​​ ​ 方法来等待我们所有的 goroutine 完成。 让我们修改之前的示例以使用 ​​sync.WaitGroup​​ :

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Println("hello, world 1")
    }()
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Println("hello, world 2")
    }()
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Println("hello, world 3")
    }()
    wg.Wait()
}

当我们运行这段代码时,我们会得到与使用 ​​time.Sleep​​ 时相同或相似的输出,运行该程序:

hello, world 3
hello, world 2
hello, world 1


参考链接:

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。