sync.Cond/コンディション変数についての解説

sync.Condを使ったコードの記述とその意味

cond.L.Lock()
for !条件 {
cond.Wait()
}
cond.L.Unlock()
lock.Lock()
if 条件 { // !条件ではなくなってるのに注意
lock.Unlock()
return
}
lock.Unlock()
lock.Lock() // クリティカルセクションをロックで守る
for !条件 { // 条件が真になるまで確認し続ける
lock.Unlock() // 自分は条件を確認したので、他のスレッドが条件を確認できるように
// ロックは解放する
// なんらかの方法でここで次の確認のタイミングを待つ lock.Lock() // また次の確認のタイミングが来たのでロックを取得する
}
lock.Unlock() // 確認が終わったのでロックを解放する
lock.Lock()
for !条件 {
lock.Unlock()
for nextCheckLoop := true; nextCheckLoop; {
nextCheckLock.Lock()
if nextCheck {
nextCheckLoop = false
}
nextCheckLock.Unlock()
time.Sleep(50*time.Milliseconds)
}

lock.Lock()
}
lock.Unlock()
lock.Lock()
for !条件 {
lock.Unlock()
<-ch
lock.Lock()
}
lock.Unlock()
「close()だな」「知ってるぞ」とどや顔
「五等分の花嫁」より。残念ながら読んだことはありません…
cond.L.Lock()
for !条件 {
cond.Wait()
}
cond.L.Unlock()
cond.L.Unlock()
// お知らせを待つ
cond.L.Lock()
cond.L.Lock()
for !条件 {
cond.Wait()
}
cond.L.Unlock()

sync.CondとBroadcastの組み合わせの使いどころ

  1. 大前提: 非同期・並行処理が発生する。
  2. ある変数の状態の遷移(「イベント」)が起こった事実を繰り返し確認する必要がある。
  3. その状態変化が起こるまでは確認スレッドは待機している必要がある。
  4. ただし、確認するタイミングは確認スレッドから見て外部要因によって決まる(例:カウントがある一定の数値を超えた、バッファが埋まった、等)。
  5. 上記の処理を繰り返し行う必要がある
  1. 「お知らせイベント」を発火する時にブロックしたくない(例:イベント自体は一気に100回くらい起こる可能性もあるが、そのイベントから待機していたスレッドは1回だけ動けばよい。チャンネルで実装するとイベント書き込み側が詰まってしまう)
  2. チャンネルで実現できない、「繰り返し同じイベントを待つ」ような条件を満たす必要がある
  1. ユーザーからの書き込みがあったタイミングでイベント発生( Broadcast )が起こり、データを書き込むスレッドを起こす
  2. データを書き込むスレッドは、バッファのサイズが閾値を超えていた時だけ書き込みを行う
  3. データ書き込みスレッドは確認と(必要であれば)書き込みが終わったあとは待機状態に戻る。

その… つまり… どういうことよ?

ツールベルトに持ってて欲しい

--

--

Go/perl hacker; author of peco; works @ Mercari; ex-mastermind of builderscon; Proud father of three boys;

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Daisuke Maki

Daisuke Maki

Go/perl hacker; author of peco; works @ Mercari; ex-mastermind of builderscon; Proud father of three boys;