GOチュートリアルには、次のスライドがあります。 Goroutines
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
このコードを実行すると、期待どおりの結果が得られます(「world」と「hello」が画面に交互に5回書き込まれます)。
ただし、time.Sleep
(したがって、インポートの"time"
行)をコメントアウトしてプログラムを再度実行すると、only画面に5回「こんにちは」と書かれました。
ゴルーチンが死ぬのを防ぐtime.Sleep
の何がそれほど重要ですか?
_time.Sleep
_を削除すると、say("world")
ゴルーチンに実行する機会が与えられません。 goroutineスケジューラーはプリエンプティブではありません。別のゴルーチンが実行される前に、ゴルーチンは制御を放棄する必要があります。コントロールを放棄する1つの方法は、_time.Sleep
_を実行することです。
say
関数から_time.Sleep
_を取り出すと、プライマリゴルーチンが5回実行され、セカンダリゴルーチンへの制御を放棄することなく、プライマリゴルーチンがsay
から戻ったときに、プログラムプログラムを存続させるものがないため、終了します。
Goroutineスケジューラはプリエンプティブではないため、別のgoroutineが実行される前に、ゴルーチンが制御を放棄する必要があります。コントロールを放棄する1つの方法は、_time.Sleep
_を使用することです。もう1つの方法は、runtime.Gosched()
を使用することです。
Gosched()を使用するように変更されたチュートリアルは次のとおりです。 http://play.golang.org/p/jQ9mlGYXXE
これは、ゴルーチンを理解する上で役立つレッスンです。ただし、スケジューラーを直接制御することは、間違いなくアンチパターンです。悲しみはしばしば続きます。
代わりに、通信するデジタルハードウェアのチャンクのようなゴルーチンについて考えてみてください(ステートマシンは良いアナロジーです)。 goroutinesのベースとなっている Communicating Sequential Processes モデルについて学習することをお勧めします。 CSPベースの設計では、各ゴルーチンは独自のプライベート状態を持ち、メッセージを交換して他のゴルーチンの状態と対話します。メッセージの受け渡しにより同期が強制され、スケジューラーはこれを使用して、CPU時間を取得するアクティビティと待機キューに配置するアクティビティを決定します。
この方法でGoにアプローチする場合、おそらくスケジューラの内部について心配する必要はありません。
time.Sleepをsay関数から削除すると、メインはsay( "hello")を実行し、ゴルーチンを実行せずに終了します。 time.Sleep(またはそれ以外の場合はselect {})をメインエンドの前に追加すると、goroutineに実行する時間を与え、そのスレッドはスケジューラから選択されます。
例:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
// time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
time.Sleep(1*time.Second)
// Vs:
// select {} // blocks indefinitely, requires manual interrupt
// In CSP-speak the empty select is like STOP.
// for{} would cause the cpu to max and the process's STATE will be `running`
// select{} will not cause the cpu to max and the process state will be `sleeping`
}
出力は通常5helloの後に5worldが続きますが、最後のhelloの前にworldの1つを印刷することもできます
TRY IT->(http://)goo.gl/K2v7H0