看一下这个人为的例子:
package main
import "fmt"
func printElo() {
fmt.Printf("Elo\n")
}
func printHello() {
fmt.Printf("Hello\n")
}
func main() {
fmt.Printf("This will print.")
i := 0
for i < 10 {
go printElo()
go printHello()
i++
}
}
该程序的输出将仅为“This will print”。 goroutines
printElo()
和printHello
的输出将不会发出,因为,我猜想main()
函数线程将在goroutines甚至有机会开始执行之前完成。使类似的代码在Golang中工作并且不提前终止的惯用方式是什么?
最佳答案
最简单,最干净和“可扩展”的方法是使用 sync.WaitGroup
:
var wg = &sync.WaitGroup{}
func printElo() {
defer wg.Done()
fmt.Printf("Elo\n")
}
func printHello() {
defer wg.Done()
fmt.Printf("Hello\n")
}
func main() {
fmt.Printf("This will print.")
i := 0
for i < 10 {
wg.Add(1)
go printElo()
wg.Add(1)
go printHello()
i++
}
wg.Wait()
}
输出(在Go Playground上尝试):This will print.Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
使用sync.WaitGroup
时要遵循的简单“规则”:WaitGroup.Add()
语句go
。WaitGroup.Done()
,因此即使goroutine panic WaitGroup
传递给其他函数(而不使用包级变量),则必须传递一个指向它的指针,否则将复制WaitGroup
(它是一个结构),并且将在副本上调用Done()
方法在原始关于go - 防止main()函数在Golang中的goroutine完成之前终止,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42752705/