技術討論區 > 程式討論版
[Golang] Wait for the goroutine end
(1/1)
Yamaka:
goroutine 有個現象,在 main() 建立 goroutine 後,如果這個函數還沒跑完,
main() 並不會等它結束後才結束整個程式,看個例子
--- 代碼: ---package main
func main() {
var count int64 = 0
go func() {
for idx := 0; idx < 200; idx++ {
count++
}
}()
println(count)
}
--- 程式碼結尾 ---
執行結果:
--- 引用 ---$ go run ex041.go
0
--- 引用結尾 ---
for 迴圈根本就還沒跑到,整個程式就 game over
整理了幾個能讓 goroutine 確實跑完的方式
(1) 利用鍵盤輸入等待
--- 代碼: ---import (
"fmt"
)
func main() {
var count int64 = 0
go func() {
for idx := 0; idx < 200; idx++ {
count++
}
}()
var in string
fmt.Scanln(&in)
println(count)
}
--- 程式碼結尾 ---
--- 引用 ---result:
200
--- 引用結尾 ---
雖然可行,不過迴圈如果要跑很久,會因為按鍵盤時間快慢,迴圈也有可能不會完全跑完
(2) 利用 channel
--- 代碼: ---func main() {
var count int64 = 0
c1 := make(chan bool)
go func() {
for idx := 0; idx < 200; idx++ {
count++
}
c1 <- true
}()
<-c1
println(count)
}
--- 程式碼結尾 ---
channel 型態不定要 bool,任何資料型態都可以,整數、字串甚至 struct 也可以
--- 代碼: ---type MyType struct {
ID int64
Name string
}
func main() {
var count int64 = 0
c1 := make(chan MyType)
go func() {
for idx := 0; idx < 200; idx++ {
count++
}
c1 <- MyType{}
}()
<-c1
println(count)
}
--- 程式碼結尾 ---
c1 目的只是要在接收資料時的等待效果。
(3) 使用 sync/WaitGroup
--- 代碼: ---import (
"sync"
)
func main() {
var count int64 = 0
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for idx := 0; idx < 200; idx++ {
count++
}
}()
wg.Wait()
println(count)
}
--- 程式碼結尾 ---
這個就比較清楚了,在使用 go 之前先告訴系統有一個 goroutine 要等待它跑完
defer wg.Done() 這行是告訴系統『我跑完嘍』
方式 1,2 適合單一 goroutine 或是數量不多時,當 goroutine 數量很多
sync/WaitGroup 就很好用,wg.Wait()會等到所有 goroutine 都結束才放行
導覽
[0] 文章列表
前往完整版本