Home > Article > Backend Development > Why does sync.Once use atomic.StoreUint32 instead of a standard assignment?
Atomic Memory Ordering in sync.Once
While exploring the source code of sync.Once, we stumble upon the reasoning behind using atomic.StoreUint32 instead of a standard assignment like o.done = 1.
Memory Ordering in Go
A fundamental concept in concurrent programming is memory ordering, which ensures that shared memory accesses are observed consistently across all processors. However, different architectures implement memory ordering differently, posing challenges for programmers.
Go addresses this by providing a uniform memory model, enforcing a relaxed but consistent memory ordering. All memory accesses are assumed to be asynchronous, with no guarantees of atomicity or ordering.
Atomic Operations in sync.Once
Despite the relaxed memory model, Go mandates the use of atomic operations for shared memory accesses to guarantee correctness across all supported architectures. In sync.Once, atomic.StoreUint32 is employed to safely update the done flag, ensuring that other goroutines can observe the effect of f() before the flag is set to 1.
Fast Path Optimization
atomic.StoreUint32 is utilized in the fast path of sync.Once to optimize performance while maintaining safety. The done flag is checked first with atomic.LoadUint32 and then written with atomic.StoreUint32 because reading the flag concurrently with writes is a data race.
Mutex Protection
The mutex used in doSlow serves to protect the done flag from concurrent writes. The flag can still be read without the mutex because it is a read operation, but concurrent writes must be synchronized to prevent data corruption.
In summary, the use of atomic.StoreUint32 in sync.Once is a consequence of Go's relaxed memory model and the necessity to guarantee thread safety on all supported architectures. By employing atomic operations, sync.Once can safely coordinate concurrent access to shared memory while optimizing performance in the fast path.
The above is the detailed content of Why does sync.Once use atomic.StoreUint32 instead of a standard assignment?. For more information, please follow other related articles on the PHP Chinese website!