程序退出时运行的 goroutine 会不会被终止
测试代码:
import (
"time"
"fmt"
)
func main() {
for i := 0; i < 10; i ++ {
go func(j int) {
fmt.Println(j)
}(i)
}
time.Sleep(3*time.Microsecond)
return
}
运行结果:
➜ test go run ./test_goroutine.go
0
1
2
3
4
5
6
7
8
9
➜ test go run ./test_goroutine.go
5
4
6
➜ test go run ./test_goroutine.go
➜ test go run ./test_goroutine.go
结论:主程序结束时还在运行中的 goroutine 也会终止。
怎样让主程序等待所有 goroutine 退出:
-
使用管道 channel,适用于单个 goroutine
func main() { ch := make(chan int) go func(c chan int){ time.Sleep(time.Second * 3) fmt.Println("goroutine 即将结束。") c <- 1 }(ch) fmt.Println("主程序即将结束。") <- ch fmt.Println("主程序退出。") }
运行结果:
主程序即将结束。 goroutine 即将结束。 主程序退出。
-
使用 WaitGroup
import ( "fmt" "sync" ) func main() { wg := sync.WaitGroup{} // wg.Add(10) for i := 0; i < 10; i++ { wg.Add(1) go func(j int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("goroutine %d 即将退出。\n", j + 1) }(i, &wg) // 此处注意使用指针传递,否则 goroutine 中的 wg 为新的对象 } fmt.Println("主程序即将退出。") wg.Wait() fmt.Println("主程序退出。") }
运行结果:
主程序即将退出。 goroutine 4 即将退出。 goroutine 1 即将退出。 goroutine 2 即将退出。 goroutine 3 即将退出。 goroutine 7 即将退出。 goroutine 5 即将退出。 goroutine 6 即将退出。 goroutine 9 即将退出。 goroutine 10 即将退出。 goroutine 8 即将退出。 主程序退出。