ホームページ > バックエンド開発 > Golang > Go で変数を共有するときにゴルーチンが異なる値を出力するのはなぜですか?

Go で変数を共有するときにゴルーチンが異なる値を出力するのはなぜですか?

Patricia Arquette
リリース: 2024-11-05 19:23:02
オリジナル
746 人が閲覧しました

Why Do Goroutines Print Different Values When Sharing Variables in Go?

Go の Goroutine シェア変数の動作

質問:

Go の同時実行機能を調べているときに、開発者は、ゴルーチン間で変数を共有するときに予期しない動作に遭遇しました。特定のコードを変更すると、出力は大きく異なります。

以下のコード スニペットでは、各ゴルーチンは対応する x 値を正しく出力します。

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)

        x := i

        go func() {
            defer wg.Done()
            fmt.Println(x)
        }()

    }

    wg.Wait()
    fmt.Println("Done")
}
ログイン後にコピー

ただし、コードはすべてのゴルーチンに対して均一な結果を生成します:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)

        go func() {
            defer wg.Done()
            fmt.Println(i)
        }()

    }

    wg.Wait()
    fmt.Println("Done")
}
ログイン後にコピー

答え:

最初のスニペットでは、各ゴルーチンには変数 x の新しいインスタンスがあります。これは、 x := i がループ反復ごとに新しい変数を作成するためです。

これを示すために、各ゴルーチン内で x のメモリ アドレスを出力できます。

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        x := i
        go func() {
            defer wg.Done()
            fmt.Println(&amp;x)
        }()
    }
    wg.Wait()
    fmt.Println("Done")
}
ログイン後にコピー

このコードを実行する各ゴルーチンの異なるメモリ アドレスが表示されます。

2 番目のスニペットでは、変数 i は go func() に渡される匿名関数で直接参照されています。これは、すべてのゴルーチンが同じ i 値を共有することを意味し、これにより出力が均一になります。

以上がGo で変数を共有するときにゴルーチンが異なる値を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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