Reputation: 14539
If I have two threads concurrently modifying a string field on a struct, will I always see one or the other string assigned to the field, but nothing else?
Upvotes: 15
Views: 8736
Reputation: 630
As of today, the version on June 6, 2022 of the Go memory model guarantees that a memory access not larger than a machine word is atomic.
Otherwise, a read r of a memory location x that is not larger than a machine word must observe some write w such that r does not happen before w and there is no write w' such that w happens before w' and w' happens before r. That is, each read must observe a value written by a preceding or concurrent write.
However, a string is definitely larger than a machine word, so your accesses are not guaranteed to be atomic. In this case, the result is unspecified, but it is most likely to be an interleave of different parts from different writes.
Reads of memory locations larger than a single machine word are encouraged but not required to meet the same semantics as word-sized memory locations, observing a single allowed write w. For performance reasons, implementations may instead treat larger operations as a set of individual machine-word-sized operations in an unspecified order. This means that races on multiword data structures can lead to inconsistent values not corresponding to a single write. When the values depend on the consistency of internal (pointer, length) or (pointer, type) pairs, as can be the case for interface values, maps, slices, and strings in most Go implementations, such races can in turn lead to arbitrary memory corruption.
Note that sync/atomic
provides not only atomicity, but also sequential consistency. As a result, for accesses not larger than machine word, sync/atomic
only provides additional sequential consistency.
The APIs in the
sync/atomic
package are collectively “atomic operations” that can be used to synchronize the execution of different goroutines. If the effect of an atomic operation A is observed by atomic operation B, then A is synchronized before B. All the atomic operations executed in a program behave as though executed in some sequentially consistent order.
The preceding definition has the same semantics as C++’s sequentially consistent atomics and Java’s volatile variables.
Upvotes: 7
Reputation: 109417
No. If you need atomic operations, there is sync/atomic
.
The Go Memory Model will have all the related details. From the top of the Memory Model document:
Programs that modify data being simultaneously accessed by multiple goroutines must serialize such access.
To serialize access, protect the data with channel operations or other synchronization primitives such as those in the
sync
andsync/atomic
packages.
Upvotes: 21