ホームページ > バックエンド開発 > Golang > Go のバッファリングされていないチャネルの出力順序が非決定的なのはなぜですか?

Go のバッファリングされていないチャネルの出力順序が非決定的なのはなぜですか?

DDD
リリース: 2024-12-07 11:03:12
オリジナル
285 人が閲覧しました

Why is the output order of Go's unbuffered channels non-deterministic?

Golang チャネルの出力順序: より深く掘り下げる

Go ではチャネルからメッセージが受信される順序を理解するのは少し難しい場合があります。あなたが提供したコードを詳しく見てみましょう:

func main() {
  messages := make(chan string)
  go func() { messages <- "hello" }()
  go func() { messages <- "ping" }()
  msg := <-messages
  msg2 := <-messages
  fmt.Println(msg)
  fmt.Println(msg2)
}
ログイン後にコピー

次の説明はあなたの懸念に対処し、何が起こっているのかをより明確に理解します:

まず、次のようなブロック操作を理解することが重要です。バッファリングされていないチャネルからの送受信は、順序を保証するものではありません。 Go では、ゴルーチンの実行は同時実行され、デフォルトではゴルーチンの実行順序は定義されていません。

最初のゴルーチンがチャネルに「hello」を送信しようとしたとき、現在待機している受信者がいない場合、ゴルーチンはブロックされました。同様に、2 番目のゴルーチンが「ping」を送信しようとすると、これもブロックされます。

ここで、msg := <-messages ステートメントに到達すると、プログラムはブロックされているゴルーチンの 1 つを任意にブロック解除します。ブロックされていないゴルーチンによって送信されたメッセージは、msg で受信されます。

同じプロセスが msg2 := <-messages でも​​発生します。別のゴルーチンのブロックが解除され、そのゴルーチンによって送信されたメッセージが msg2 で受信されます。

ゴルーチンのブロックが解除されてメッセージがメッセージに送信される順序は決定的ではありません。これが、ルーチンが代わりに実行されるはずであると仮定していたにもかかわらず、一貫して「hello」の前に「ping」が出力される理由です。

これを確認するには、ゴルーチンに print ステートメントを追加してみてください。

func main() {
  messages := make(chan string)
  go func() {
    fmt.Println("Sending 'hello'")
    messages <- "hello"
    fmt.Println("Sent 'hello'")
  }()
  go func() {
    fmt.Println("Sending 'ping'")
    messages <- "ping"
    fmt.Println("Sent 'ping'")
  }()
  msg := <-messages
  msg2 := <-messages
  fmt.Println(msg)
  fmt.Println(msg2)
}
ログイン後にコピー

コードを数回実行すると、ゴルーチンからの print ステートメントの順序が異なる場合があることがわかります。これは、ゴルーチン実行の非決定的な性質をさらに示しています。

要約すると、バッファリングされていないチャネルでは、チャネルからの出力の順序は保証されず、対応するゴルーチンのブロックが解除される順序に依存します。

以上がGo のバッファリングされていないチャネルの出力順序が非決定的なのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート