看看这个人为的例子:
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()
and printHello
不会被发射,因为,我猜,main()
函数线程将在 goroutine 有机会开始执行之前完成。
让类似的代码在 Golang 中工作并且不会提前终止的惯用方法是什么?
最简单、最干净且“可扩展”的方法是使用sync.WaitGroup https://golang.org/pkg/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()
}
输出(尝试一下去游乐场 https://play.golang.org/p/6L64RRPEW1):
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
:
- call WaitGroup.Add() https://golang.org/pkg/sync/#WaitGroup.Add在“原始”goroutine(开始一个新的)之前go https://golang.org/ref/spec#Go_statements陈述
- 建议致电WaitGroup.Done() https://golang.org/pkg/sync/#WaitGroup.Done延迟,所以即使 Goroutine 发生恐慌,它也会被调用
- 如果你想通过
WaitGroup
对于其他函数(并且不使用包级变量),您必须传递一个指向它的指针,否则WaitGroup
(这是一个结构)将被复制,并且Done()
在副本上调用的方法不会在原始版本上观察到
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)