views:

556

answers:

6

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; }
A: 

If you examine the auto-generated code, you'll see that auto-generated properties are NOT thread safe - they are simple get/set to a generated field. In fact, it would be too much of a performance hit to do so (especially when not needed).

In addition, if you are planning on access int/bool values from multiple threads then you should mark it (the field) as volatile. This basically prevents multithreading issues related to CPU registers. (This is in addition to locking, not an alternative)

Richard Szalay
This is wrong. You are confusing the atomicatity of memory with visibility amongst threads. All read/writes of variables with size less than the native int are guaranteed to be atomic. See section 12.6.6 of the CLI language spec for more details.
JaredPar
You are right - I did mean thread safe (not atomic). Serves me right for answering so early in the morning ;)
Richard Szalay
@Richard, In the morning I often stay away from SO until I've finished my coffee for my own safety. Or at least my reps :)
JaredPar
That's a good policy :D
Richard Szalay
A: 

I would think not. Properties are essentially just methods with a bit of syntactic sugar on them to make them a little easier to work with. So by default they're no more thread-safe than a normal method call (which is to say, not thread-safe at all).

Jonathan Schuster
+2  A: 

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.

JaredPar
+14  A: 

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.

Jon Skeet
Thanks. I assumed "atomic" meant atomic everywhere, including across threads. That's what the word suggested to me. Threading really is fraught with danger.
dangph
A: 

Atomicity just means that if more than one thread is writing to a variable, its value won't get corrupted (e.g. if it takes up two bytes, you will never get thread one's high byte and thread two's low byte). It does not mean the variable is thread-safe. You can still get the usual threading problems of one thread not seeing anothers changes etc.

For thread-safety you need to use locking (or volatile, but this is harder to reason about). There is nothing special about properties - they need to be made explicitly thread-safe too.

Jon
+1  A: 

You can put anything in a property, e.g

    Public Property foo() As Boolean
        Get
           goToLunch()
           barbecueRibs()
           return m_foo
        End Get
        Set(ByVal value As Boolean)
           takeANap()
           accessDatabase()
           messUpOtherVariables()
           m_foo = value
        End Set
    End Property
Larry Watanabe