スケジューラーのソースコードは、src/pkg/runtime/proc.c
スケジューラーのルールは以下のとおり(GOMAXPROC=1の場合)
- goruntineは、non preemptiveマルチタスクのように動作する。ある時点で動作しているgoruntineは1つのみ。
- 別のgoroutineが動き出すのは、今動作しているgoroutineが明示的に待ちに入るときのみ。channelのread/write、systemcallの呼び出しなど。
goroutineを実行するthreadは、上記のルールに合うように、必要に応じて作成される。あるgoroutineをどのthreadが実行しているか、は、考える必要がない(考えてもあまり意味がない)。
goroutineはtimesliceで切り替わりはしない
2つのgoroutineがrunning状態だとする。一方が
for {
}
のようにbusy loopしていると、もう一方のgoroutineは全く動かないので、プログラムの動作はそこで止まってしまう。
のように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 件のコメント:
コメントを投稿