sync.WaitGroup


1 min read
sync.WaitGroup

Goroutineを使用して複数の処理を並列で実行、すべてが終わったら次の処理に進みたいという場合があると思います。
Goroutineでデータのリストを作るという処理を考えます。
データの順番は関係なく、すべてのGoroutineでのデータがそろったら次の処理をしたいという設定です。
この場合、単純に考えると以下のようなコードになりますが、以下のコードではデータがそろう前に次の処理が行われます。

datalist := []string{}
for i := 0; i < 10; i++ {
    go func() {
        // something w/datalist
    }
}
fmt.Println("next step")

このような場合に、sync.WaitGroupを使用します。
sync.WaitGroupは基本的にはただのカウンタですが、カウンタがゼロになるまで処理を待つことができます。
言葉で説明してもわかりにくいと思いますので、ソースコードを見てみましょう。

datalist := []string{}
wg := sync.WaitGroup{}

for i := 0; i < 10; i++ {
    wg.Add(1) // Goroutineの数だけカウンタを増やす
    go func() {
        // something w/datalist
        wg.Done() // カウンタを減らす
    }
}
wg.Wait() // カウンタが0になるまでブロックする
fmt.Println("next step")

上記の様にすることで、for文の部分ではGoroutineで並列に実行しつつ、次の処理は並列実行部分が終わってからという動作をさせることができます。

ポイントはカウンタを増やす部分です。
Goroutine内ではなく、外側でAdd(1)します。
Goroutine内でAdd(1)してしまうと、wg.Wait()に到達した時点でGoroutineがまだどれも実行されておらず、次の処理に進んでしまう可能性があるので、必ずGoroutineの外側で実行することが肝要です。


Go 1.9 is released
Previous article

Go 1.9 is released

先日2017年8月24日にGo 1.9がリリースされました。 ダウンロードページからダウンロード可能です。 最大の変更点はGo1.9rc1 is released!でもお伝えしたように、Type Aliasでしょう。 型名に対して別名をつけることができる機能です。 また、そのほかにも多くの変更が加えられています。 リリースノートはこちらです。 以下では、いくつか変更点を見ていきます。 Ports Go 1.9から新しく2つのOSと1つのプロセッサアーキテクチャがサポートされています。 POWER8 IBMのPOWER8プロセッサがサポートされています。 GOARCH=ppc64またはGOARCH=

io.Writer.Write()とfmt.Fprintf()のBenchmark
Next article

io.Writer.Write()とfmt.Fprintf()のBenchmark

tl;dr 基本的にio.Writer.Write()を使用するのが高速なようです。 result $ go test -bench . -benchmem BenchmarkWrite-4 30000000 48.7 ns/op 16 B/op 1 allocs/op BenchmarkWriteWithBytes-4 500000000


GO TOP

🎉 You've successfully subscribed to something tech.!
OK