Go Lang の不正な同期
Go メモリ モデルのドキュメントでは、次のコードにより g print 2 が発生する可能性があると説明されています。 0:
var a, b int
func f() {
a = 1
b = 2
}
func g() {
print(b)
print(a)
}
func main() {
go f()
g()
}
説明:
- 変数 a と b は、関数が実行される前にゼロ値 (0) に初期化されます。
- Go メモリ モデル内の Happens Before ルールにより、コンパイラとプロセッサは、次の場合に単一のゴルーチン内の操作を並べ替えることができます。並べ替えはその動作には影響しません。
- f() 関数では、並べ替えによってゴルーチンに違いが生じない場合、a と b への代入が指定された順序で行われない可能性があります。
- 割り当ては f() 関数に影響を及ぼさないため、コンパイラは効率上の理由から割り当てを並べ替える場合があります。
- 同期がないため提供された例の 2 つのゴルーチン (f() と g()) の間で、コンパイラーはそれらの間の一貫性を保証しようとしません。
- ただし、ゴルーチン間に同期を導入すると、コンパイラーは同期ポイントで両方の割り当てが「完了」することが保証されます。これは、正しい値 (2 と 1) が g() に出力されることを意味します。
以上がWhy Might Go\ の `go f(); g()` \'21\' の代わりに \'20\' を出力しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。