Go 语言入门很简单:WaitGroup

举报
宇宙之一粟 发表于 2022/10/31 19:33:10 2022/10/31
4.1k+ 0 0
【摘要】 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

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

    全部回复

    上滑加载中

    设置昵称

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

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

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