Goの勉強 ゴルーチンとチャネル

Goの勉強をやり始めたのでメモ。
プログラミング言語 Go」を読んでる。

ゴルーチン

  • とりあえずスレッドみたいなもの(厳密には違うらしい)
  • main関数を呼び出すゴルーチンはメインゴルーチンと呼ぶ
  • 新たなゴルーチンは go 文で生成できる
  • main関数が終了するとすべてのゴルーチンも終了する
  • mainから戻ることとプログラムを終了させること以外に他のゴルーチンを終了させる方法はない
    • ゴルーチンの停止をリクエストするために他のゴルーチンと通信する方法はある

チャネル

  • チャネルはゴルーチン間の接続
    • ひとつのゴルーチンから他のゴルーチンへ値を送ることができる
  • チャネルはマップと同様に make で作成する。
    • つまり参照になる。
  • 同じ型のチャネルは == で比較可能である。
  • チャネルは「送信」と「受信」の操作を持ち、まとめて「通信」と呼ばれる。
  • 他に、クローズという操作もある。
ch <- x // 送信  
x = <-ch // 受信  
close(ch) // クローズ  

バッファなしチャネル

  • バッファなしチャネルは送信と受信を同期させるために使用する。
  • チャネルに送信されるメッセージのことをイベントと呼ぶ。
  • 同期のみが目的の場合、チャネルの型は struct{} にすることが一般的である。

パイプライン

  • チャネルを使って複数のゴルーチンを接続することをパイプラインと呼ぶ。
  • チャネルは使用した後にすべて閉じる必要はない。
    • 到達不能なチャネルはガベージコレクタがその資源を回収する。

一方向チャネル

  • 送信用、受信用のチャネルを型で宣言することができる。
  • 引数でチャネルを渡すと暗黙的に送信用、受信用に型変換される。
  • 双方向チャネルから一方向チャネルに型変換することはできるが、逆はできない。
chan<- int // 送信用  
<-chan int // 受信用  

バッファありチャネル

ch = make(chan string, 3)  

とすることで容量が3のバッファありチャネルを作成することができる。

  • チャネルがいっぱいになるまで受信を待たずに送信することができる。
  • チャネルが空になるまで送信を待たずに受信することができる。
  • チャネルが空でもいっぱいでもなければ、送信・受信ともにすることができる。

select での多重化

受け取ったチャネルによって処理を変更したいときに select を使う。

select {  
case <-ch1:  
        // ....  
case x := <-ch2:  
        // ....  
case ch3 <- y:  
        // ....  
default:  
        // ....  
}  
  • select{} は永久に待ち続ける。
  • 複数のチャネルから受信可能であれば、どのチャネルが選ばれるかはランダムに選択される。

以下のような処理はポーリングと呼ばれる。

for {  
        select {  
                case <- abort:  
                        return  
                default:  
                        // 何もしない  
        }  
}