Go の以前のバージョンでは、runtime.Gosched() が使用されていた場合、以下のコードは予期しない動作を示しました。削除されました:
package main import ( "fmt" "runtime" ) func say(s string) { for i := 0; i < 5; i++ { runtime.Gosched() fmt.Println(s) } } func main() { go say("world") say("hello") }
で出力runtime.Gosched():
hello world hello world hello world hello world hello
runtime.Gosched() を使用しない出力:
hello hello hello hello hello
GOMAXPROCS 環境変数を指定せずに Go を実行すると、すべてgoroutine は、単一の OS スレッドで実行されるようにスケジュールされます。プログラムをマルチスレッドとして見せるには、Go スケジューラーは実行コンテキストを時々切り替える必要があります。
協調マルチタスク:
Go は協調マルチタスク モデルを使用します。つまり、ゴルーチンは明示的に制御を譲る必要があります。他のゴルーチンに。これは、スケジューラが実行コンテキストを透過的に切り替える OS スレッドのプリエンプティブ マルチタスクとは対照的です。
runtime.Gosched() の関数:
プリエンプティブ マルチタスクがない場合, runtime.Gosched() を使用すると、ゴルーチンが制御をスケジューラーに渡すことができます。 goroutine が Gosched 呼び出しに到達すると、スケジューラは別の goroutine に実行を切り替えるように指示します。
上記の例では、Gosched を削除するということは、実行コンテキストがメイン ルーチンから離れることがないことを意味します。その結果、「world」ゴルーチンの実行は決して許可されず、「world」メッセージは出力されません。
GOMAXPROCS を正の数に設定 (例: runtime.GOMAXPROCS(2)) により、Go はその数までネイティブ スレッドを作成できます。 GOMAXPROCS が 1 より大きい場合、ゴルーチンを別のスレッドで実行するようにスケジュールでき、真の並列処理が可能になります。
GOMAXPROCS を 2 以上に設定すると、ランタイムがなくても、例のゴルーチンはインターリーブされます。Gosched ()、プリエンプティブ マルチタスクを示します。
以上がシングルスレッドの Go プログラムで Goroutine 出力をインターリーブするのに「runtime.Gosched()」が重要なのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。