Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are reads and writes to properties atomic in C#?

Tags:

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; } 
like image 386
dan-gph Avatar asked Jul 20 '09 05:07

dan-gph


People also ask

Are read and write Atomic?

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).

Why are read and write Atomic?

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.

What is non atomic attributes?

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.

What is atomic and non atomic?

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.


2 Answers

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.

like image 121
Jon Skeet Avatar answered Sep 18 '22 18:09

Jon Skeet


I'm a little unclear as to what you are asking here. It seems like you could be asking 1 of 2 questions

  1. Is the read of _foo while calling MyProperty atomic?
  2. Is the return value of MyProperty atomically set?

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.

like image 27
JaredPar Avatar answered Sep 20 '22 18:09

JaredPar