Edited at

ブロックせずにチャネルに値を送信する方法

More than 5 years have passed since last update.

チャネルに何かの値を送信したいけど、チャネルのバッファがすでに一杯ならそれ以上は送りたくない(送信待ちでブロックしたくない)という状況がある。

たとえば設定の再読み込みの責任を担っているgoroutineがいるとしよう。そのgoroutineは普段はあるチャネルで何か値が送られてくるのを待っていて、値が送られてくると動作を再開して、設定をどこかから読み込む(そのあとロックを獲得してグローバルな設定データを更新するというのが普通だが、それはここでは関係がない)。

さて、そういうgoroutineでは複数回連続して動作するのは通常特に意味がない。従って、設定再読み込みリクエストは1個でも2個でもどちらでもよくて、むしろ複数個連続してチャネルに値が送信されても1個しかキューされないようにしたいだろう。

そういうふうな動作を実現するには下のコードのようにすれば良い。

// バッファサイズ1のチャネルを作成

c := make(chan bool, 1)

// ブロックせずに送信できるなら送信する。そうでなければ何もしない。
select {
case c <- true:
default:
}

注意: capでバッファに空きがあるかどうかを調べてからチャネルに送信するのはダメだよ。複数のgoroutineがcapを同時に実行して、両方とも空きがあると判断したら、送信のタイミングで結局どちらかがブロックしてしまうので。上のようにやること。