ホームページ  >  記事  >  バックエンド開発  >  Go 同時実行性: チャネルの使用時にプログラムが予期しない出力を出力するのはなぜですか?

Go 同時実行性: チャネルの使用時にプログラムが予期しない出力を出力するのはなぜですか?

DDD
DDDオリジナル
2024-10-28 16:16:17905ブラウズ

Go Concurrency: Why Does My Program Print Unexpected Output When Using Channels?

Go の同時実行性とチャネルの混乱の解決

Go で同時実行性を使用する場合、チャネルはゴルーチン間の通信において極めて重要な役割を果たします。ただし、それらの動作は時々混乱を引き起こす可能性があります。

次の Go プログラムを考えてみましょう:

<code class="go">package main

import "fmt"

func display(msg string, c chan bool) {
    fmt.Println("display first message:", msg)
    c <- true
}

func sum(c chan bool) {
    sum := 0
    for i := 0; i < 10000000000; i++ {
        sum++
    }
    fmt.Println(sum)
    c <- true
}

func main() {
    c := make(chan bool)

    go display("hello", c)
    go sum(c)
    <-c
}</code>

プログラムが意図した動作は、「最初のメッセージを表示: hello」を出力して終了することです。 。ただし、実際の出力には sum 関数の結果が含まれます。

display first message: hello
10000000000

説明

混乱は、メインの goroutine が次の行でブロックしているという事実から生じます。

<code class="go"><-c</code>

これは、チャネル c から値を受信するまでメイン goroutine が実行を続行できないことを意味します。 display と sum の両方が true 値を c に送信し、メインの goroutine のブロックを解除します。ただし、スケジューラはどの goroutine を最初に実行するかを選択できます。

可能な実行順序:

  1. Main は表示用と合計用の 2 つの goroutine を作成します。
  2. スケジューラは表示を実行します。最初にメッセージを出力し、チャネル送信をブロックします。
  3. スケジューラは sum ゴルーチンに切り替わります。
  4. Sum が計算され、結果が出力されます。
  5. スケジューラは表示を再開します。 、チャネルに値を送信します。
  6. メインの goroutine は値を受信して​​終了します。

ソリューション

プログラムは最初の結果のみを出力します。結果チャネルを使用できます:

<code class="go">func display(msg string, result chan string) {
    result <- msg
}</code>

そして main 関数を次のように変更します:

<code class="go">func main() {
    result := make(chan string)

    go display("hello", result)
    fmt.Println(<-result)
}</code>

以上がGo 同時実行性: チャネルの使用時にプログラムが予期しない出力を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。