sync.Once でのアトミック メモリの順序付け
sync.Once のソース コードを探索しているときに、アトミックを使用する背後にある理由に遭遇しました。 o.done = 1 のような標準的な割り当ての代わりに StoreUint32 を使用します。
Go でのメモリの順序付け
同時プログラミングの基本的な概念はメモリの順序付けです。これにより、共有メモリが確実に共有されます。アクセスはすべてのプロセッサにわたって一貫して観察されます。ただし、アーキテクチャが異なるとメモリの順序付けの実装方法が異なるため、プログラマにとって課題が生じます。
Go は、統一されたメモリ モデルを提供し、緩和的だが一貫したメモリ順序付けを強制することでこの問題に対処します。すべてのメモリ アクセスは非同期であると想定され、原子性や順序性の保証はありません。
同期したアトミック操作。Once
緩和されたメモリ モデルにもかかわらず、Go は共有メモリアクセスにアトミック操作を使用して、サポートされているすべてのアーキテクチャにわたって正確性を保証します。 sync.Once では、atomic.StoreUint32 を使用して Done フラグを安全に更新し、フラグが 1 に設定される前に他のゴルーチンが f() の効果を監視できるようにします。
高速パスの最適化
atomic.StoreUint32 は、安全性を維持しながらパフォーマンスを最適化するために、sync.Once の高速パスで利用されます。書き込みと同時にフラグを読み取るとデータ競合が発生するため、完了フラグは最初に atomic.LoadUint32 でチェックされ、次に atomic.StoreUint32 で書き込まれます。
Mutex Protection
doSlow で使用される mutex は、done フラグを同時書き込みから保護するために機能します。フラグは読み取り操作であるため、ミューテックスなしでも読み取ることができますが、データの破損を防ぐために同時書き込みを同期する必要があります。
要約すると、sync.Once での atomic.StoreUint32 の使用は次の結果です。 Go の緩和されたメモリ モデルと、サポートされているすべてのアーキテクチャでスレッド セーフを保証する必要性。アトミック操作を採用することで、sync.Once は高速パスでのパフォーマンスを最適化しながら、共有メモリへの同時アクセスを安全に調整できます。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3