一尘不染

通道上sync.WaitGroup的优点是什么?

go

我正在研究并发的Go库,偶然发现了goroutine之间两种相似的同步模式,其结果相似:

使用等待组

var wg sync.WaitGroup
func main() {
        words := []string{ "foo", "bar", "baz" }

        for _, word := range words {
                wg.Add(1)
                go func(word string) {
                        time.Sleep(1 * time.Second)
                        defer wg.Done()
                        fmt.Println(word)
                }(word)
        }
        // do concurrent things here

        // blocks/waits for waitgroup
        wg.Wait()
}

使用频道

func main() {
        words = []string{ "foo", "bar", "baz" }
        done := make(chan bool)
        defer close(done)
        for _, word := range words {
                go func(word string) {
                        time.Sleep(1 * time.Second)
                        fmt.Println(word)
                        done <- true
                }(word)
        }

        // Do concurrent things here

        // This blocks and waits for signal from channel
        <-done
}

有人告诉我,sync.WaitGroup它的性能要好一些,而且我已经看到它被普遍使用。但是,我发现频道更惯用了。sync.WaitGroup通过渠道使用的真正优势是什么?和/或更好的情况又可能是什么情况?


阅读 206

收藏
2020-07-02

共1个答案

一尘不染

独立于第二个示例的正确性(如注释中所述,您没有按照自己的想法进行操作,但是很容易修复),我倾向于认为第一个示例更容易掌握。

现在,我什至不会说渠道更加惯用。通道是Go语言的一种签名功能,并不意味着在任何可能的情况下使用它们都是惯用的。Go的惯用用法是使用最简单,最容易理解的解决方案:在这里,WaitGroup传达含义(您的主要职能是Wait完成工作)和机制(工作人员在工作时通知Done)。

除非您的情况非常特殊,否则我不建议您在此使用渠道解决方案。

2020-07-02