質問: ``` package main func main(){ go func1() go func2() go func3() for{ } } func func1(){ for{ } } func func2(){ for{ } } func func3(){ for{ } } ``` 上のような構造のコードを作成しましたが、それぞれの関数のgoroutineが動きません。このことはそれぞれのgoroutineの最初にprint文を使い確かめました。それぞれのfor文は無限ループです。また、それぞれの関数ではTwitterのStreaming APIを使って、情報を取得しています。 goのバージョンは`go version go1.4.2 linux/arm`です。 このような実装はできないのでしょうか、それとも、Twitter Streaming APIの影響でできなくなっているのでしょうか。
回答: Go1.4までは、デフォルトでCPUを1コアしか使わないようになっています。 なぜCPUを1コアしか使っていないのに複数のgoroutineを同時に実行できるのかというと、適当なタイミングで実行するgoroutineをつぎつぎに切り替えているからです。(スケジューリング) ただし、この切り替えのタイミングは特定の操作を行った場合に限られます。 このページ()によると、チャンネル操作・ロック・関数呼び出し、だそうです。 つまり、何もしていない無限ループに入ってしまうと、他のgoroutineに切り替えるタイミングがありません。どれか一つのgoroutine内の`for{}`に到達するとそのループでCPUを占有し続けるため、他のgoroutineが実行できなくなってしまいます。 今回の場合はmain内のループで止まってしまっているのだと思います。他のgoroutineのループに先に到達すれば当然そちらで止まってしまいます。 ``` // こういうのもダメです for { i += 1 } ``` ループ内で「チャンネル操作・ロック・関数呼び出し」のいずれかを行うか、もしくは1コアCPUのRaspberry Piでは無理ですが`GOMAXPROCS`で使用するコア数を増やしてやれば解決します。