メインの goroutine はチャネルから信号を受信するまでブロックしているにもかかわらず、Go プログラムが指定されたコード スニペットのメッセージの前に計算の合計を出力するのはなぜですか?

DDD
リリース: 2024-10-29 21:49:29
オリジナル
492 人が閲覧しました

Why does the Go program print the sum of the computation before the message in the given code snippet, even though the main goroutine blocks until a signal is received from the channel?

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>
ログイン後にコピー

このコードでは、display と sum という 2 つのゴルーチンを作成します。表示ゴルーチンはメッセージを出力し、チャネルに信号を送信して、応答を待ちます。 sum ゴルーチンは、長い計算を実行し、結果を出力し、チャネルに信号を送信します。メインのゴルーチンでは、チャネルからシグナルを受信するまでブロックします。

コードの期待される出力は次のとおりです。

display first message: hello
ログイン後にコピー

ただし、プログラムが両方のメッセージを出力することがわかります。計算の合計:

display first message: hello
10000000000
ログイン後にコピー

問題の理解

この問題は、ゴルーチンのスケジューリングの非決定的な性質により発生します。 Go のスケジューラは、ブロックされていないゴルーチンの中から自由に選択します。この例では、スケジューラはいつでも任意のゴルーチンを実行できます。

可能な実行順序の 1 つは次のとおりです。

  1. main はゴルーチンを作成します。
  2. スケジューラは表示を選択し、メッセージを出力して応答を待ちます。
  3. スケジューラは合計に切り替わり、長時間実行されます。
  4. スケジューラは表示に戻り、シグナルを送信します。 .
  5. スケジューラはメインに切り替わり、信号を出力して終了します。

このシナリオでは、ディスプレイが信号を送信する前に合計が出力されるため、予期しない出力が発生します。

解決策

プログラムがメッセージのみを出力し、合計が計算される前に終了するようにするには、別のアプローチを使用できます。

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

    go display("hello", result)
    go sum(result)

    fmt.Println(<-result)
}</code>
ログイン後にコピー

この改訂版では、結果チャネルは単一の値、つまり表示ゴルーチンからのメッセージを伝えます。メインの goroutine はチャネルからの値を出力し、終了する前にメッセージを確実に受信するようになりました。

以上がメインの goroutine はチャネルから信号を受信するまでブロックしているにもかかわらず、Go プログラムが指定されたコード スニペットのメッセージの前に計算の合計を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!