Go 範例:WaitGroup

若要等到多個 goroutine 執行完畢,可以使用等待組

package main
import (
    "fmt"
    "sync"
    "time"
)

這是我們將在每個 goroutine 執行的函式。

func worker(id int) {
    fmt.Printf("Worker %d starting\n", id)

睡眠,以模擬耗時的工作。

    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
}
func main() {

使用此 WaitGroup 來等待於此啟動的所有 goroutine 執行完畢。注意:如果明確將 WaitGroup 傳遞至函式,則應傳遞指標來執行。

    var wg sync.WaitGroup

啟動多個 goroutine,並為每個 goroutine 增加 WaitGroup 計數器。

    for i := 1; i <= 5; i++ {
        wg.Add(1)

將 worker 呼叫包覆在閉包中,以確保通知 WaitGroup 此 worker 已完成。如此一來,worker 本身不需知道與執行相關的並行處理原語。

        go func() {
            defer wg.Done()
            worker(i)
        }()
    }

等到 WaitGroup 計數器回到 0,表示所有 worker 已通知完成。

    wg.Wait()

請注意,此方法沒有直接的方法可以從 worker 傳遞錯誤。對於更進階的使用案例,請考慮使用 errgroup 套件

}
$ go run waitgroups.go
Worker 5 starting
Worker 3 starting
Worker 4 starting
Worker 1 starting
Worker 2 starting
Worker 4 done
Worker 1 done
Worker 2 done
Worker 5 done
Worker 3 done

worker 的啟動與結束順序在每次呼叫時可能皆會不同。

下一個範例:速率限制