运行 代码与 goroutine 并行的首选语法是什么?
What is the preferred syntax to run code in parallel with goroutine?
假设我需要调用一个函数两次。通常的做法是:
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
doSomething(A)
wg.Done()
}()
go func() {
doSomething(B)
wg.Done()
}()
wg.Wait()
}
但是这样写呢?
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
doSomething(A)
wg.Done()
}()
doSomething(B)
wg.Done()
wg.Wait()
}
我们节省了创建一个 goroutine 的时间,同时使用了 main goroutine。但是我从来没有在任何教程中看到过这样写的。这样做错了吗?我已经做了测试,输出结果和我一样。
两者都是正确的。如果您打算稍后扩展您的代码,例如,第一种形式更清晰并且可以很好地扩展。如果您稍后决定要启动的不是 2 个而是 3 个或 4 个或 N 个 goroutine,代码的结构不会改变,您只需添加额外的 goroutine。
第一种形式是 "popular" 的另一个原因是因为通常在启动 "worker" goroutines 之后有更多的事情要做,可以在这个 goroutine 上执行(在 wg.Done()
之前称为)。
另一方面,第二种形式更高效,因为它只启动一个额外的 goroutine。 Goroutines 是轻量级的,廉价的,但它们不是 "free"。这可以通过使用 WaitGroup
仅 "track" 启动的 goroutine 来进一步改进,显然调用 wg.Wait()
的 "main" 不需要明确地等待自己。如果只剩下 1 个 goroutine,您可以使用其他同步方式而不是 WaitGroup
(例如通道)。
所以基本上,如果性能很重要,请使用第二种方法。
假设我需要调用一个函数两次。通常的做法是:
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
doSomething(A)
wg.Done()
}()
go func() {
doSomething(B)
wg.Done()
}()
wg.Wait()
}
但是这样写呢?
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
doSomething(A)
wg.Done()
}()
doSomething(B)
wg.Done()
wg.Wait()
}
我们节省了创建一个 goroutine 的时间,同时使用了 main goroutine。但是我从来没有在任何教程中看到过这样写的。这样做错了吗?我已经做了测试,输出结果和我一样。
两者都是正确的。如果您打算稍后扩展您的代码,例如,第一种形式更清晰并且可以很好地扩展。如果您稍后决定要启动的不是 2 个而是 3 个或 4 个或 N 个 goroutine,代码的结构不会改变,您只需添加额外的 goroutine。
第一种形式是 "popular" 的另一个原因是因为通常在启动 "worker" goroutines 之后有更多的事情要做,可以在这个 goroutine 上执行(在 wg.Done()
之前称为)。
另一方面,第二种形式更高效,因为它只启动一个额外的 goroutine。 Goroutines 是轻量级的,廉价的,但它们不是 "free"。这可以通过使用 WaitGroup
仅 "track" 启动的 goroutine 来进一步改进,显然调用 wg.Wait()
的 "main" 不需要明确地等待自己。如果只剩下 1 个 goroutine,您可以使用其他同步方式而不是 WaitGroup
(例如通道)。
所以基本上,如果性能很重要,请使用第二种方法。