バッファありチャネルとバッファなしチャネル

先日、ゴルーチンとチャネルを使った以下のようなプログラムを作成したところ、うまく動作しませんでした。

メインのゴルーチンがチャネルに送信して、もうひとつのゴルーチンがチャネルから受信するだけのプログラムです。送信側と受信側の双方とも forselect を使ってポーリングをしています。しかし、実行してみてもまったく送信されません。

調べたところ、バッファなしチャネル(unbuffered channel)を使っているのが原因だとわかりました。バッファなしチャネルを介した通信は、送信しているゴルーチンと受信しているゴルーチンを同期させるため、送信側のゴルーチンが送信の状態で、かつ、受信側のゴルーチンが受信の状態でないと、通信が行われません。

解決するには、上のプログラムの2つのゴルーチンのどちらかの select を使わないようにするか、以下のようにバッファありチャネル(buffered channel)を使うように変更します。

参考文献

  • 「プログラミング言語Go」 Alan A.A. Donovan (著),‎ Brian W. Kernighan (著),‎ 柴田 芳樹 (翻訳)