ホームページ > バックエンド開発 > Golang > Go 同時実行の例で、予想されるシーケンスではなく「6, 6, 6, 6, 6」が出力されるのはなぜですか?

Go 同時実行の例で、予想されるシーケンスではなく「6, 6, 6, 6, 6」が出力されるのはなぜですか?

DDD
リリース: 2024-11-29 12:26:11
オリジナル
618 人が閲覧しました

Why Does My Go Concurrency Example Print

for ループと匿名関数による Go の同時実行: 予期せぬ事態を明らかにする

Go で同時実行コードを記述する場合、匿名関数の動作を理解することが重要です。この例では、for ループと匿名関数が予期しない出力を生成するシナリオを検討します。

初期コード

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go func() {
            fmt.Println(i)
            time.Sleep(time.Second * 1)
            wg.Done()
        }()
    }

    wg.Wait()
}
ログイン後にコピー

このコードを実行すると、驚くべきことに「6, 6, 6,予想されるシーケンス「2、4、1、5、3」ではなく、「6、6」です。これは、ゴルーチンが起動された後も for ループが変数 i を更新し続けるためです。

クロージャ

上記のコードの匿名関数はクロージャです。クロージャは、関数の作成時に関数の本体で使用される変数をキャプチャします。この場合、変数 i はゴルーチンの起動時に取得されます。ただし、ループはゴルーチンの開始後も i を更新し続けます。

説明

i が 5 より大きくなるまでループは終了しないため、ゴルーチンが最終的に実行されるとき、i は 6 になります。したがって、各ゴルーチンは、クロージャでキャプチャされた i の値 (この場合は 6) を出力します。期待される出力は、変数 i が引数として匿名関数に渡された場合にのみ観察され、呼び出し時に値のコピーが事実上作成されます。

以上がGo 同時実行の例で、予想されるシーケンスではなく「6, 6, 6, 6, 6」が出力されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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