技術討論區 > 程式討論版

[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] 文章列表

前往完整版本