问题描述
独立于第二个示例的正确性(如注释中所述,您没有按照自己的想法进行操作,但是很容易修复),我倾向于认为第一个示例更容易掌握。
现在,我什至不会说渠道更加惯用。通道是Go语言的一种签名功能,并不意味着在任何可能的情况下使用它们都是惯用的。Go的惯用用法是使用最简单,最容易理解的解决方案:在这里,WaitGroup
传达含义(您的主要职能是Wait
完成工作)和机制(工作人员在工作时通知Done
)。
除非您的情况非常特殊,否则我不建议您在此使用渠道解决方案。
解决方法
我正在研究并发的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","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
通过渠道使用的真正优势是什么?和/或更好的情况又可能是什么情况?