Go のメモリ モデルでは、同時実行ゴルーチンで予期しない出力が発生するのはなぜですか?

Susan Sarandon
リリース: 2024-11-25 00:42:10
オリジナル
259 人が閲覧しました

Why Does Go's Memory Model Allow Unexpected Output in Concurrent Goroutines?

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート