防止main()函数在Golang中的goroutine完成之前终止
看一下这个人为的例子:
package mainimport "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甚至有机会开始执行之前完成。
使类似的代码在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.HelloElo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
执行以下操作时要遵循的简单“规则” sync.WaitGroup
:
WaitGroup.Add()
在go
语句之前调用“原始” goroutine(开始一个新的)- 建议调用
WaitGroup.Done()
延迟,因此即使goroutine恐慌也可以调用 - 如果要传递
WaitGroup
给其他函数(而不使用全局变量),则必须传递一个指向它的指针,否则WaitGroup
将复制(它是一个结构),并且Done()
在复制时将不会观察到该方法原本的
以上是 防止main()函数在Golang中的goroutine完成之前终止 的全部内容, 来源链接: utcz.com/qa/427738.html