ホームページ バックエンド開発 Golang Go ルーチンのデータ競合で、Go コードが「One」、「Two」、「Three」ではなく「Three」を 3 回出力するのはなぜですか?

Go ルーチンのデータ競合で、Go コードが「One」、「Two」、「Three」ではなく「Three」を 3 回出力するのはなぜですか?

Dec 07, 2024 pm 10:23 PM

Why Does My Go Code Print

データ競合シナリオにおけるゴルーチンの奇妙な動作を理解する

提供された Go コードでは、data と呼ばれる構造体フィールドのスライスを作成します。 「one」、「two」、「three」という名前が含まれています。コードはスライスを反復処理し、print メソッドを使用して各フィールドの名前を出力するゴルーチンを作成します。ただし、予想に反して、コードは意図した "one"、"two"、"three" の順序ではなく、"three" を 3 回繰り返し出力します。

データ競合の解明

この奇妙な動作は、複数のゴルーチンが同じ共有データに同時にアクセスし、変更する可能性があるときに発生するデータ競合に起因します。この場合、ゴルーチンの作成時に範囲変数 v のアドレスが暗黙的に使用されるために問題が発生します。ループ変数 v が各反復で変更されると、ゴルーチンは最終値を使用することになり、その結果、常に「three」が出力されます。

データ競合への対処

この問題を解決するには、いくつかの方法を採用できます。アプローチ:

  • 各ループ反復での新しい変数の作成: ループ内で、範囲変数と同じ名前の新しい変数を宣言し、効果的に変数を作成できます。の新しいスコープvariable.

  • ポインターのスライスの使用: 構造体フィールドのスライスを使用する代わりに、フィールドへのポインターのスライスを使用できます。これにより、ゴルーチンが個々のフィールド要素へのポインタを確実に受け取り、データ競合の問題を防ぐことができます。

  • スライス要素のアドレスを渡す: 別の代替方法は、次のとおりです。スライス内の各要素のアドレスをgoroutine.

  • 匿名関数の使用と引数として範囲変数の受け渡し: goroutine 関数が匿名関数内にある場合、次のように渡すことで問題を回避できます。への引数としての範囲変数function.

これらのアプローチにより、ゴルーチンが必要なデータの独自のコピーを確実に保持し、データ競合が排除され、「one」、「two、」の正しい出力が生成されます。 「」と「3」は順不同です。

以上がGo ルーチンのデータ競合で、Go コードが「One」、「Two」、「Three」ではなく「Three」を 3 回出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Mar 03, 2025 pm 05:17 PM

Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか?

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? Mar 10, 2025 pm 05:38 PM

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか?

Beegoフレームワークのページ間で短期情報転送を実装する方法は? Beegoフレームワークのページ間で短期情報転送を実装する方法は? Mar 03, 2025 pm 05:22 PM

Beegoフレームワークのページ間で短期情報転送を実装する方法は?

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? Mar 10, 2025 pm 05:36 PM

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか?

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? Mar 10, 2025 pm 03:20 PM

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか?

Go言語でファイルを便利に書く方法は? Go言語でファイルを便利に書く方法は? Mar 03, 2025 pm 05:15 PM

Go言語でファイルを便利に書く方法は?

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? Mar 03, 2025 pm 05:18 PM

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は?

GOの実際のパフォーマンスを正確に反映するベンチマークを作成するにはどうすればよいですか? GOの実際のパフォーマンスを正確に反映するベンチマークを作成するにはどうすればよいですか? Mar 10, 2025 pm 05:36 PM

GOの実際のパフォーマンスを正確に反映するベンチマークを作成するにはどうすればよいですか?

See all articles