Goroutineの文法を自分用メモとしてまとめる。
sync.WaitGroup
複数のスレッドで並列処理を行う際、その全ての完了を確認するために使用できる。WaitGroupのカウンタを用いる。(Javaのjava.util.concurrent.CountDownLatchによく似ているらしい)
// WaitGroupの値を作る
wg := &sync.WaitGroup{}
// wgのカウントをインクリメント
wg.Add(1)
go func(wg *sync.WaitGroup) {
// wgのカウントをデクリメント
defer wg.Done()
処理
}
// カウントが0なら次に進める
wg.Wait()
処理
[注意] Addされるカウントの合計 = Done()の合計個数
である必要あり
チャネル
- 中身の個数が決まってるのが
bufferred channel
、決まっていないのがunbufferred channel
。
// チャネルの作成
ch = make(chan int)
// チャネルへ値を突っ込む
ch <- x
// チャネルから値を取り出す
y := <- ch
// チャネルの中身をループ
// もし他にプログラムが入っていない、つまり、このchに新しい値が入る可能性がないならばループ前にcloseする必要あり
close(ch)
for c := range ch {
処理
}
-
fan out
/fan in
// 順にfan out / fan in
def(first <-chan int, second chan<- int){
処理
}
- { 無限for, select文 }からの抜け方
Outerloop:
for {
select {
case <-ch:
fmt.Println("Out!")
break OuterLoop
default:
処理
}
}
}
sync.mutex
複数のgoroutineから一つの変数を書き換えたいときに使う。
// お目当ての変数とMutexを含む構造体を定義する
type Counter struct{
v map[string]int
mux sync.Mutex
}
// それを使う
func (c *Counter) Inc(key string) int {
c.mux.Lock()
defer c.mux.Unlock()
return c.v[key]++
}