sync.WaitGroup

ゴルーチンの終了待ちには、チャネルを使うほかに sync パッケージの WaitGroup を使う方法もある。
使い方はこうだ:

  1. sync.WaitGroup の変数を作る
  2. その変数に、終了待ちをするゴルーチンの数を設定する
  3. ゴルーチンを呼び出す。このとき、sync.WaitGroup の変数を渡す
  4. ゴルーチン側では、終了したら Done 関数を呼ぶ
  5. メインルーチン側で、Wait 関数を呼ぶ

実際に試してみよう。

package main

import (
    "fmt"
    "time"
    "sync"
)

func test(n int, name string, wg *sync.WaitGroup) {
    for i := 0; i < n; i++ {
        fmt.Println(i, name)
        time.Sleep(500 * time.Millisecond)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup wg.Add(3)
    go test(6, "foo", &wg)
    go test(4, "bar", &wg)
    go test(8, "baz", &wg) wg.Wait()
}
^o^ > go run go_waitgroup.go
0 baz
0 bar
0 foo
1 baz
1 bar
1 foo
2 baz
2 bar
2 foo
3 baz
3 bar
3 foo
4 baz
4 foo
5 baz
5 foo
6 baz
7 baz