等待 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 按執行順序使用:

  1. 全域性變數宣告。使其全域性化是使其對所有函式和方法可見的最簡單方法。
  2. 增加櫃檯。這必須在主 goroutine 中完成,因為由於記憶體模型保證, 無法保證新啟動的 goroutine 將在 4 之前執行。
  3. 減少櫃檯。這必須在 goroutine 的出口處完成。通過使用延遲呼叫,我們確保無論函式如何結束都會在函式結束時呼叫它。
  4. 等待計數器達到 0.這必須在主 goroutine 中完成,以防止程式在所有 goroutine 完成之前退出。

* 在開始新的 goroutine 之前評估引數。因此,有必要在 wg.Add(10) 之前明確定義它們的值,以便可能恐慌的程式碼不會增加計數器。向 WaitGroup 新增 10 個專案,因此它將等待 10 個專案,然後 wg.Wait 將控制權返回給 main() goroutine。這裡,i 的值在 for 迴圈中定義。