Golang のチャネル出力順序を理解する
次の Golang プログラムについて考えてみましょう:
func main() { messages := make(chan string) go func() { messages <- "hello" }() go func() { messages <- "ping" }() msg := <-messages msg2 := <-messages fmt.Println(msg) fmt.Println(msg2) }
このプログラムには 2 つのゴルーチンが含まれますチャネルに非同期に書き込み、メイン ルーチンが同じチャネルから読み取ります。チャネルのバッファリングされていない性質にもかかわらず、出力では一貫して「ping」と「hello」が出力されます。
この出力の背後にある理由を理解するには、チャネルの出力順序が次の順序に基づいていないことを理解することが重要です。これでゴルーチンが作成されます。代わりに、スケジューラによって決定され、非決定的な方法でゴルーチンの実行順序が決定されます。
プログラムが実行されると、チャネルへのメッセージの送信を担当する 2 つのゴルーチンが同時に実行されます。チャネルはバッファリングされていないため、レシーバーが使用可能になるまで両方のゴルーチンがブロックされます。
メイン ルーチンが msg := <-messages を使用してチャネルから読み取ろうとすると、スケジューラは待機中のゴルーチンの 1 つへのアクセスを許可します。 。このゴルーチンはメッセージをチャネルに正常に送信し、その後メイン ルーチンによって受信され、msg に割り当てられます。
その後、メイン ルーチンが msg2 := <-messages を使用してチャネルから再度読み取ろうとすると、の場合、スケジューラは残りの goroutine を選択し、そのメッセージをチャネルに送信できるようにします。次に、メッセージはメイン ルーチンによって取得され、msg2.
に割り当てられます。この特定のケースでは、スケジューラは一貫して、メッセージを最初に送信するゴルーチンとして「ping」を送信するゴルーチンを選択します。ただし、この結果は非決定的であり、システム負荷や実行環境などの要因に基づいて変化する可能性があることに注意することが重要です。
要約すると、Golang チャネルでの出力順序は保証されず、スケジューラによるゴルーチンの実行順序。したがって、この例は単純であるにもかかわらず、出力は実行ごとに異なる可能性があります。
以上がこの Go プログラムは、同時チャネル書き込みにもかかわらず、「ping」を出力してから「hello」を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。