TL;DR

  • Go のチャネルは、性能を上げるためにランタイムのスケジューラに組み込まれている。
  • 一時停止した受信側と送信側のゴルーチンを並べる 2 つのリンクリストと、保留中のメッセージを入れるバッファを持つ。

内容

チャネルは、性能を上げるためにランタイムのスケジューラに組み込まれている。実装は src/runtime/chan.go にある。

チャネルは 3 つのものを持つ。一時停止させた受信側ゴルーチンへの参照を入れるリンクリスト、送信側ゴルーチンへの参照を入れるリンクリスト、そして保留中のメッセージを入れるバッファである。

バッファがいっぱいのとき、またはバッファなしチャネルのときは、新しく来た送信側ゴルーチンが一時停止され、送信側リストに並ぶ。逆にバッファが空のときは、新しく来た受信側ゴルーチンが一時停止され、受信側リストに並ぶ。

2 つのリストは、ゴルーチンを再開するときに使われる。メッセージが利用できるようになると、受信側リストの先頭のゴルーチンが再開される。新しい受信側が現れると、送信側リストに待っているゴルーチンがあれば、その先頭のゴルーチンが再開される。

キーワード