Go でゴルーチンを起動するときにデータ競合を回避するにはどうすればよいですか?
Dec 08, 2024 pm 05:37 PM同時実行 Go ルーチンでのデータ競合
このコードは、同時実行 Go でのデータ競合の問題を示しています。ルーチン:
package main import ( "fmt" "time" ) type field struct { name string } func (p *field) print() { fmt.Println(p.name) } func main() { data := []field{{"one"}, {"two"}, {"three"}} for _, v := range data { go v.print() } <-time.After(1 * time.Second) }
ログイン後にコピー
問題:
コードは、どのコードでも「one」、「two」、「three」を出力するのではなく、「three」を 3 回出力します。注文。これは、データ競合が存在するためです。
説明:
コードは、ゴルーチン関数の引数を評価するときに、暗黙的に変数 v のアドレスを取得します。ゴルーチン関数 v.print() は (&v).print() と同等です。ループは v の値を変更し、ゴルーチンが実行されると、たまたまループの最後の値 (「three」) を持ちます。
修正:
このデータ競合を修正するには、いくつかの方法があります。
- 内に新しい変数を作成します。ループ:
for _, v := range data { v := v // short variable declaration of new variable `v`. go v.print() }
ログイン後にコピー
- ポインタのスライスを使用:
data := []*field{{"one"}, {"two"}, {"three"}} // note '*' for _, v := range data { go v.print() }
ログイン後にコピー
- スライスのアドレスを使用する要素:
data := []field{{"one"}, {"two"}, {"three"}} // note '*' for i := range data { v := &data[i] go v.print() }
ログイン後にコピー
- 範囲変数を引数として無名関数に渡します:
for _, v := range data { go func(v field) { v.print() // take address of argument v, not range variable v. }(v) }
ログイン後にコピー
以上がGo でゴルーチンを起動するときにデータ競合を回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

人気の記事
スプリットフィクションを打ち負かすのにどれくらい時間がかかりますか?
3週間前
By DDD
レポ:チームメイトを復活させる方法
3週間前
By 尊渡假赌尊渡假赌尊渡假赌
ハローキティアイランドアドベンチャー:巨大な種を手に入れる方法
3週間前
By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.説明されたエネルギー結晶と彼らが何をするか(黄色のクリスタル)
1週間前
By 尊渡假赌尊渡假赌尊渡假赌

人気の記事
スプリットフィクションを打ち負かすのにどれくらい時間がかかりますか?
3週間前
By DDD
レポ:チームメイトを復活させる方法
3週間前
By 尊渡假赌尊渡假赌尊渡假赌
ハローキティアイランドアドベンチャー:巨大な種を手に入れる方法
3週間前
By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.説明されたエネルギー結晶と彼らが何をするか(黄色のクリスタル)
1週間前
By 尊渡假赌尊渡假赌尊渡假赌

ホットな記事タグ

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック
Gmailメールのログイン入り口はどこですか?
7281
9


Java チュートリアル
1622
14


CakePHP チュートリアル
1341
46


Laravel チュートリアル
1258
25


PHP チュートリアル
1205
29



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

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

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

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

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

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