goroutineを調べたときに深掘りしたときに調べたまとめ
並行処理プログラミングのモデル
Shared memory
いわゆるプログラミング言語のランタイムによるアプリケーションスレッド(グリーンスレッド)である
同じプロセス(LWP)内でランタイムによりスイッチされながら実行される並行化の仕組みなので、マルチコアにスケールはしない
[同じプロセス(LWP)内で動く = メモリ空間を共有する]ためグローバルオブジェクトなどへの共有メモリアクセスを制限するため、ランタイム側で実行中のアプリケーションスレッドにロックを取得させている
ロックを取得・開放を繰り返して、スイッチさせながら複数のアプリケーションスレッドを実行しているためCPUバウンドの処理の場合はパフォーマンスは改善しない(むしろスイッチコストがかかるため悪くなる)
ただし、IOバウンドの処理の場合は、IO waitの時にロックが開放されるため効率よく並列化できる。
ネットワークIOやファイルIOを多重化する場合は、アプリケーションスレッドでも効率的に並列化できる
Message passing
Shared memoryがメモリアドレスを共有するのに対して、Message passingは共有しない
データをメッセージとしてやり取りすることにより、送り手と受け手の中でのみメモリ空間を論理的に管理する(送り手と受け手のメモリ空間をライブラリレベルで論理的に管理する)
actor modelが有名
Implicit Interaction
並列化をプログラミングコードレベルでは意識せずに、コンパイラやインタプリターで暗黙的に実現する。 プログラマは並列化を意識せずにコードを書くが、コンパイル時に並列実行できるようなコードに変換される(インタプリタの場合は実行時)
並列プログラミングにおける問題のカテゴリ
タスク並列化
データ並列化
暗黙的な並列化
用語
コルーチン
サブルーチンが手続き全体を処理する塊に対して、途中で明示的に実行を停止して制御を返すことができる処理
Pythonで言うyield文を使ったジェネレータ的な
goroutine
CSP (Communicating Sequential Processes)という理論にもとづいている
- goroutineアプリケーションスレッドのスケジューリング
- スタック管理
- ネットワークIO
goroutine は並行性(並列性ではない)を扱いやすくするための機能です。複数スレッドで独立した関数を多重化して coroutine のように実行するというアイデアは以前からありました。 ブロッキングするシステムコールを呼び出したときなどで、ある coroutine がブロックするとき、ランタイムは自動的に OS の同一システムスレッド上で他の coroutine が一緒にブロックされないように、実行可能な別のスレッド上に移動します。プログラマがこれを意識しない、これが重要な点です
軽量スレッドと捉えるよりも、内部的にはジェネレータみたいな呼び出し待ちををランタイムがスケジューリングしてるイメージなのかな。
だからcoroutineをもじって、goroutineなのかな
http requestハンドリングでのgoroutine
golangの標準パッケージのhttp serverの実装はgoroutine per request(connection)になってた(http/server.go#2668)
libuvのような非同期IOを使ったコールバックよりも、goroutineによる並行化の戦略をとってるっぽい
そういうもんなんだろうか、、、?
参考
Parallel programming model
https://en.wikipedia.org/wiki/Parallel_programming_model
Go 言語の goroutine と channel についての考察
http://qiita.com/izariuo440/items/9e1b1faabcee6e2e94c0
イベントループなしでのハイパフォーマンス – C10K問題へのGoの回答
http://postd.cc/performance-without-the-event-loop/
Coroutine
http://qiita.com/fujimisakari/items/811e350cbaeb45b6165e
Go の並行処理
http://jxck.hatenablog.com/entry/20130414/1365960707
「サーバ書くなら epoll 使うべき」は、今でも正しいのか
http://developer.cybozu.co.jp/archives/kazuho/2009/09/epoll-bac0.html