技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

goroutine、sync.WaitGroup【Go】

goroutineは、プログラムの並行処理を実現します。
goroutineはマルチスレッドのようなもので、
goroutineの起動毎に回路が作られ、その中で処理が行われます。
起動方法は、次の通りです。

go 関数(またはメソッド)

以降に記述された処理が、goと記載された処理の終了をまたずに起動されます。
goroutineを複数起動することもできます。

次の処理に対して、goroutineの終了を待たせたい場合には、
syncパッケージのWaitGroup構造体を使用します。
WaitGroupはgoroutineの個数を管理し、次のメソッドを持ちます。

func (wg *sync.WaitGroup).Add(delta int)    // 管理する個数をdelta分だけ増やす
func (wg *sync.WaitGroup).Done()    // その処理の完了を表し、管理する個数から-1する
func (wg *sync.WaitGroup).Wait()    // 管理する個数が0になるまで、次の処理をブロックする

各メソッドには、WaitGroupのポインタを渡す必要があります。

使用例を示します。

func ex(wg *sync.WaitGroup) {
    defer wg.Done()    // 処理が完了したことを告げ、管理する個数から-1する
    for i := 0; i < 5; i++ {
        fmt.Println("!")
    }
}

func world(wg *sync.WaitGroup) {
    defer wg.Done()    // 処理が完了したことを告げ、管理する個数から-1する
    for i := 0; i < 5; i++ {
        fmt.Println("world")
    }
}

func hello() {
    for i := 0; i < 5; i++ {
        fmt.Println("hello")
    }
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    go ex(&wg)    // アドレス(ポインタ)を渡す
    go world(&wg)    // アドレス(ポインタ)を渡す
    hello()
    wg.Wait()
    fmt.Println("finish!")    // wgの完了を待つ
}

helloが5回、worldが5回、!が5回出力された後、finish!が出力されます。
(hello、world、!の順番が入れ替わることがあります。)

ota42y.com