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(&x) }() } wg.Wait() fmt.Println("Done") }
このコードを実行する各ゴルーチンの異なるメモリ アドレスが表示されます。
2 番目のスニペットでは、変数 i は go func() に渡される匿名関数で直接参照されています。これは、すべてのゴルーチンが同じ i 値を共有することを意味し、これにより出力が均一になります。
以上がGo で変数を共有するときにゴルーチンが異なる値を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。