程序退出時運行的 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
}
運行結(jié)果:
? 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
結(jié)論:主程序結(jié)束時還在運行中的 goroutine 也會終止西壮。
怎樣讓主程序等待所有 goroutine 退出:
-
使用管道 channel闷哆,適用于單個 goroutine
func main() { ch := make(chan int) go func(c chan int){ time.Sleep(time.Second * 3) fmt.Println("goroutine 即將結(jié)束冶共。") c <- 1 }(ch) fmt.Println("主程序即將結(jié)束很钓。") <- ch fmt.Println("主程序退出挨队。") }
運行結(jié)果:
主程序即將結(jié)束狈茉。 goroutine 即將結(jié)束。 主程序退出恩急。
-
使用 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("主程序退出此叠。") }
運行結(jié)果:
主程序即將退出。 goroutine 4 即將退出随珠。 goroutine 1 即將退出灭袁。 goroutine 2 即將退出。 goroutine 3 即將退出窗看。 goroutine 7 即將退出茸歧。 goroutine 5 即將退出。 goroutine 6 即將退出显沈。 goroutine 9 即將退出软瞎。 goroutine 10 即將退出。 goroutine 8 即將退出。 主程序退出铜涉。