Go Lang での不正な同期
Go メモリ モデルでは、単一の goroutine 内で読み取りと書き込みが実行されたかのように動作する必要があると指定されています。プログラムで指定された順序。ただし、次のコードに示すように、複数の goroutine を使用すると特有の動作が発生します。
var a, b int func f() { a = 1 b = 2 } func g() { print(b) print(a) } func main() { go f() g() }
ドキュメントによると、コードでは最初に「2」を出力し、次に「0」を出力する可能性があります。予想される「1」と「2」。なぜこのようなことが起こるのでしょうか?
コード内では連続しているように見えますが、f ゴルーチン内では a と b への代入が順序どおりに行われないことがあります。ゴルーチンは代入後の変数を使用しないため、コンパイラは変数の順序を変更することで最適化できます。
ただし、f ゴルーチンと g ゴルーチンの間で同期がないため、コンパイラは出力時の一貫性を保証できません。結果として、両方の代入が同じゴルーチン内で発生する場合、b の値が a の値より前に観察される可能性があります。
正確さを保証するには、ゴルーチン間の同期が必要です。同期ポイントで、コンパイラは両方の割り当てが完了したことを保証します。たとえば、同期ポイントが print 呼び出しの前に配置される場合、新しい値 (2 と 1) が正しく出力され、誤った動作が防止されます。
以上がGo のメモリ モデルでは、同時実行ゴルーチンで予期しない出力が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。