ホームページ  >  記事  >  バックエンド開発  >  Go プログラムが「最初のメッセージの表示」の前に合計結果を出力することがあるのはなぜですか?

Go プログラムが「最初のメッセージの表示」の前に合計結果を出力することがあるのはなぜですか?

DDD
DDDオリジナル
2024-10-30 18:16:03725ブラウズ

 Why does my Go program sometimes print the sum result before the

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」を出力し、その後に合計の計算の結果を出力することが想定されています。ただし、場合によっては、表示関数がデータをチャネルに送信する前に合計の計算が終了することがあります。

説明:

Go のスケジューラは、ゴルーチンの順序を決定します。が実行されます。これは非決定的であり、実行順序はハードウェアやオペレーティング システムなどの要因によって異なる可能性があります。この例では:

  1. main 関数は、display と sum の 2 つのゴルーチンを作成します。
  2. スケジューラは、最初に display ゴルーチンに切り替えることを選択し、「display first message」行を出力します。 .
  3. まだ受信者が存在しないため、表示ゴルーチンはチャネル (c <- true) にデータを送信しようとするとブロックされます。
  4. スケジューラーは合計ゴルーチ​​ンを実行することを選択します。これにより、計算量の多いループが実行されます。
  5. 合計の計算が完了すると、合計ゴルーチ​​ンはチャネルにデータを送信します。
  6. main 関数はチャネルからデータを受信して​​終了します。

ただし、表示ゴルーチンがチャネルにデータを送信する前に、スケジューラが合計ゴルーチ​​ンを完了まで実行することも可能です。この場合、出力は次のようになります:

10000000000
display first message: hello

解決策:

合計結果の前に表示メッセージが確実に出力されるようにするには、結果を使用できます。チャネルを選択して最初の結果を受信し、プログラムを終了します。変更された main 関数は次のようになります:

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

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

以上がGo プログラムが「最初のメッセージの表示」の前に合計結果を出力することがあるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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