google-code-prettify

2012-08-23

Goのgoroutineのスケジューリング

Go言語のgoroutineのスケジューリングに関して調べた。
スケジューラーのソースコードは、src/pkg/runtime/proc.c

スケジューラーのルールは以下のとおり(GOMAXPROC=1の場合)

  1. goruntineは、non preemptiveマルチタスクのように動作する。ある時点で動作しているgoruntineは1つのみ。
  2. 別のgoroutineが動き出すのは、今動作しているgoroutineが明示的に待ちに入るときのみ。channelのread/write、systemcallの呼び出しなど。

goroutineを実行するthreadは、上記のルールに合うように、必要に応じて作成される。あるgoroutineをどのthreadが実行しているか、は、考える必要がない(考えてもあまり意味がない)。

goroutineはtimesliceで切り替わりはしない

2つのgoroutineがrunning状態だとする。一方が
for {
}
のようにbusy loopしていると、もう一方のgoroutineは全く動かないので、プログラムの動作はそこで止まってしまう。

goroutineを実行するthreadは切り替わる

goroutineがwait状態から解除されたとする。解除前と解除後では、そのgoroutineを実行しているthreadが違うものの可能性がある。(goのプログラムを書く上では、あまり気にしなくて良いが)

threadは、goroutineを走らせるのに必要な場合だけ作成される

threadは、goroutineを走らせるのに必要な場合だけ作成される。

あるgoroutineがsystem callでブロックする場合、そのgoroutineを実行しているthreadもブロックしてしまう。runningなgoroutineが存在するのに、それを実行できる(ブロックしていない)threadが存在しない場合にのみ、threadは作成される。

goroutineがchannelのread/writeでブロックする場合、そのgoroutineを実行中だったthreadは、goroutineのステートをブロック状態にし、別のrunnableなgoroutineの実行を開始する。この場合には、新たなthreadを作る必要は無いので、threadは作成されない。


0 件のコメント: