Reads and writes to certain primitive types in C# such as bool
and int
are atomic.
(See section 5.5, "5.5 Atomicity of variable references", in the C# Language Spec.)
But what about accessing such variables via properties? Is it reasonable to assume that they will also be atomic and thread-safe? E.g. Is a read of MyProperty
below atomic and thread-safe?:
public bool MyProperty { get { return _foo; } }
And what about auto-implemented properties?
public bool MyProperty { get; }
Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double). Reads and writes are atomic for all variables declared volatile (including long and double variables).
For example, when accessing or mutating a property is atomic, it means that only one read or write operation can be performed at a time. If you have a program that reads a property atomically, this means that the property cannot change during this read operation. In Swift, operations on a dictionary are not atomic.
Non atomic properties has no guarantee regarding the returned value . It can be the correct value, a partially written value or even some garbage value. As most things that are not safe — this comes with enhanced speed of accessing this properties.
Atomic means only one thread accesses the variable (static type). Atomic is thread-safe, but it is slow. Nonatomic means multiple threads access the variable (dynamic type). Nonatomic is thread-unsafe, but it is fast.
You need to distinguish between "atomic" and "thread-safe" more closely. As you say, writes are atomic for most built-in value types and references.
However, that doesn't mean they're thread-safe. It just means that if values "A" and "B" are both written, a thread will never see something in between. (e.g. a change from 1 to 4 will never show 5, or 2, or any value other than 1 or 4.) It doesn't mean that one thread will see value "B" as soon as it's been written to the variable. For that, you need to look at the memory model in terms of volatility. Without memory barriers, usually obtained through locking and/or volatile variables, writes to main memory may be delayed and reads may be advanced, effectively assuming that the value hasn't changed since the last read.
If you had a counter and you asked it for its latest value but never received the latest value because of a lack of memory barriers, I don't think you could reasonably call that thread-safe even though each operation may well be atomic.
This has nothing to do with properties, however - properties are simply methods with syntactic sugar around them. They make no extra guarantees around threading. The .NET 2.0 memory model does have more guarantees than the ECMA model, and it's possible that it makes guarantees around method entry and exit. Those guarantees should apply to properties as well, although I'd be nervous around the interpretation of such rules: it can be very difficult to reason about memory models sometimes.
I'm a little unclear as to what you are asking here. It seems like you could be asking 1 of 2 questions
_foo
while calling MyProperty atomic?For #1 the answer is yes. As the C# language spec (and CLI) states, the read and write of variables of certain specified types are guaranteed to be atomic. The type 'bool' is one of those types.
As for #2 the best place to look is section 12.6.6 of the CLI spec. It states that
A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size (the size of type native int) is atomic
Considering to use the return value of MyProperty you must either be reading or writing the value, it's safe to assume it is set atomically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With