Go言語:Goroutines

Goroutinesの話

goroutine (ゴルーチン)は、Goのランタイムに管理される軽量なスレッドです。

  • go 関数呼び出しで新しいスレッドで処理される。
    • プログラムは、スレッドの処理の終了を待つわけではない。
    • 新しいスレッドで処理が始まるのに(ノンブロックの状態で)遅延がある。
  • Channelsを使うと、簡単に同期的な処理が書ける。
    • 条件を明示せずに、同期を許可する、ということらしい。
    • Channelsの操作には、channel operator <-を用いる。
    • channel <- x でChannelsに値を送信、y := <- channelで受信し変数へ値を割り当てる。
  • Channelsの生成には、makeを用いる。
    • make( chan 型 )
    • 型以外の値を送信しようとすると、cannot use xxx (type xxxの型) as type 正しい型 in sendとしてコンパイルに失敗する。

書いてみる1

Goroutines:ベーシック

sample.goの出力

  • goroutineでの処理が遅れて実行される。
  • goroutineでない処理とは並行して処理が進む。
0 second
0 first
1 second
1 first
2 second
2 first
3 second
3 first
4 second
4 first

sample.nooutput.goの出力

  • なにも出力されない。
    • プログラムのほうが早く終了する、という理解で合ってる?

sample.sleep.goの出力

  • goの呼び出しの後にsleepを入れた。
  • goroutineでの処理が先に実行される。
    • たまたま、1ミリ秒以内でgoroutineの処理が先に始まった、という方が正しいかもだが。
0 first
0 second
1 first
1 second
2 first
2 second
3 first
3 second
4 first
4 second

書いてみる2

Goroutines:ポインタ

ポインタはgoroutineでないときと同じように振る舞うらしい。

出力

1 0 1
2 0 2
3 0 1
1 1 3
2 1 4
3 1 2
1 2 5
2 2 6
3 2 3
1 3 7
2 3 8
3 3 4
1 4 9
2 4 10
3 4 5
10

書いてみる3

  • ポインタで書くより明らかにわかりやすい。
  • 同期したいタイミングが明示できる。

Goroutines:Channels

invoke Channel A
1 0 1
2 0 2
1 1 2
2 1 4
1 2 3
2 2 6
1 3 4
2 3 8
1 4 5
2 4 10
5 10
invoke Channel B
3 0 3
3 1 6
3 2 9
3 3 12
3 4 15
4 0 4
4 1 8
4 2 12
4 3 16
4 4 20
15 20