goroutine編GoはじめにGoでは、goroutineとchannelが言語仕様として組み込まれているため、他の言語に比べてとても並行処理のコードが書きやすい。この2つの基本的な動作原理についてまとめた自分用のメモである。(channelについては別の記事で書く予定)goroutineとは?goroutine(ゴールーチン)とは、他のコードに対して並行に実行している関数のことgoroutineはgoというキーワードを関数呼び出しの前に置くことで起動できる。簡単!あらゆるGoのプログラムでは、main関数を動かすためのgoroutineが必ず存在する。Goを支えるとてもプリミティブなものである。goキーワードを使ってgoroutineを動かすとても簡単な例としては以下になる。}このコードは以下の2つのgoroutineで動作している。main関数を動かしているgoroutinemain関数から分岐した、sayHello関数を動かしているgoroutinegoroutineの正体ではgoroutineとは何なのだろうか?Javaなどの他の言語をやってきた人からすると、これはスレッドとして実行されているのか?と気になるところだが、実態はスレッドではない。P.38では以下のように説明されている。ゴルーチンはOSスレッドではなく、また必ずしもグリーンスレッド――言語のランタイムにより管理されるスレッド――ではありません。ゴルーチンはコルーチン(coroutine)として知られる高水準の抽象化です。コルーチンは単に「プリエンプティブでない」並行処理のサブルーチン(Goでは関数、クロージャー、メソッドに相応)です。割り込みをされることがないということです。かわりに、コルーチンには一時停止や再エントリーを許す複数のポイントがあります。ランタイムと密結合していることです。一時停止や再エントリーのポイントを定義していません。ランタイムはゴルーチンの実行時の振る舞いを観察し、ゴルーチンがブロックしたら自動的に一時停止し、ブロックが解放されたら再開します。これによってある意味ゴルーチンをプリエンプティブにしていますが、ゴルーチンがブロックしたときにしか割り込みません。以上のことから、ゴルーチンは特殊なコルーチンと考えられます。goroutineはGoのランタイムにより管理されるため、Goのコードから一時停止したりレジュームすることはできない(channelやcontextを使えば動作を止めるようにキャンセルすることは可能)。これがコルーチンとは違う点だと思う。goroutineとして関数を実行してもスレッドが新しく作られるわけではないので、スレッドよりも軽量である。スケジューラーと呼ばれる実装になっています。スレッドに対応させるものです。ゴルーチンはグリーンスレッドにスケジュールされます。グリーンスレッドの数よりも多い数のゴルーチンがある場合には、スケジューラーはゴルーチンを利用可能なグリーンスレッドに割り振って、これらのゴルーチンがブロックした場合には他のゴルーチンを実行するようにしています。fork-joinモデルGoではfork-joinモデルと呼ばれる並行処理のモデルに従っている。分岐した時点より以降に、平行処理されている親と子が再び合流すること図で表すと以下のようになる。ここで先ほどのsayHelloを使ったgoroutineの例を見てみる。}sayHelloはgoroutineとして実行された後にjoinしていないので、helloと表示されずにこのプログラムは終わってしまう。mainに合流させるにはどうしたらよいだろうか?一番簡単なやり方は以下のようにsync.WaitGroupを使うことである。}https://play.golang.org/p/-uPFeh_37mBまとめこれがgoroutineの基本的なことの全てである。goというキーワードを使うだけで並行処理が簡単に書けるということがわかるはず。