views:

3874

answers:

4

Is accessing a bool field atomic in C#? In particular, do I need to put a lock around:

class Foo
{
   private bool _bar;

   //... in some function on any thread (or many threads)
   _bar = true;

   //... same for a read
   if (_bar) { ... }
}
+24  A: 

Yes.

Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types.

as found in C# Language Spec.

Edit: That said, you should probably mark it as volatile.

Larsenal
Wait a second... reads and writes to reference types (e.g. any Object) is atomic?
Chris
The pointer itself, reassigning it, is atomic (i.e. Foo foo1 = foo2;
In my experience volatile is generally not a great idea: if you need volatile, you generally care about "simultaneous" actions - and even with a volatile, those are quite easy to get wrong. For instance the above if statement would require quite a bit of extra plumbing if it's to avoid many threadings entering - and if the aim is only to avoid entering until some thread has passed `_bar = true;` at least once, not using volatile at worst means that the if statement won't be take temporarily even though _bar is true. I'd suggest to just use locks if precision is required.
Eamon Nerbonne
+1 for marking the field as `volatile`.
Yann Trevin
+7  A: 

bool accesses are indeed atomic, but that isn't the whole story.

You don't have to worry about reading a value that is 'incompletely written' - it isn't clear what that could possibly mean for a bool in any case - but you do have to worry about processor caches, at least if details of timing are an issue. If thread #1 running on core A has your _bar in cache, and _bar gets updated by thread #2 running on another core, thread #1 will not see the change immediately unless you add locking, declare _bar as volatile, or explicitly insert calls to Thread.MemoryBarrier() to invalidate the cached value.

McKenzieG1
"it isn't clear what that could possibly mean for a bool in any case "Items that exist in only one byte of memory at atomic because the entire byte is written to at the same time. Versus items like double which exist in multiple bytes, one byte could be written before the other byte and you could observe a half written memory location.
MindStalker
+2  A: 

As stated above bool is atomic but you still need to remeber that it also depends on what you want to do with it. if(b == false) { //do something } is not an atomic operation meaning that b value could change before the current thread executes the code after the if statement.

Dror Helper