等待 goroutines
當 main
函式結束時 ,程式結束 ,因此通常的做法是等待所有 goroutine 完成。一個常見的解決方案是使用 sync.WaitGroup物件。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup // 1
func routine(i int) {
defer wg.Done() // 3
fmt.Printf("routine %v finished\n", i)
}
func main() {
wg.Add(10) // 2
for i := 0; i < 10; i++ {
go routine(i) // *
}
wg.Wait() // 4
fmt.Println("main finished")
}
WaitGroup 按執行順序使用:
- 全域性變數宣告。使其全域性化是使其對所有函式和方法可見的最簡單方法。
- 增加櫃檯。這必須在主 goroutine 中完成,因為由於記憶體模型保證, 無法保證新啟動的 goroutine 將在 4 之前執行。
- 減少櫃檯。這必須在 goroutine 的出口處完成。通過使用延遲呼叫,我們確保無論函式如何結束 ,都會在函式結束時呼叫它。
- 等待計數器達到 0.這必須在主 goroutine 中完成,以防止程式在所有 goroutine 完成之前退出。
* 在開始新的 goroutine 之前評估引數。因此,有必要在 wg.Add(10)
之前明確定義它們的值,以便可能恐慌的程式碼不會增加計數器。向 WaitGroup 新增 10 個專案,因此它將等待 10 個專案,然後 wg.Wait
將控制權返回給 main()
goroutine。這裡,i 的值在 for 迴圈中定義。