看一下这个人为的例子:
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”。goroutine的输出printElo()并且printHello不会被发出,因为我想main()函数线程将在goroutines甚至有机会开始执行之前完成。
printElo()
printHello
main()
使类似的代码在Golang中工作并且不提前终止的惯用方式是什么?
最简单,最干净和“可扩展”的方法是使用sync.WaitGroup:
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()
WaitGroup
Done()