Is it safe to read an integer variable that's being concurrently modified without locking?

Suppose that I have an integer variable in a class, and this variable may be concurrently modified by other threads. Writes are protected by a mutex. Do I need to protect reads too? I've heard that there are some hardware architectures on which, if one thread modifies a variable, and another thread reads it, then the read result will be garbage; in this case I do need to protect reads. I've never seen such architectures though.

This question assumes that a single transaction only consists of updating a single integer variable so I'm not worried about the states of any other variables that might also be involved in a transaction.


atomic read
As said before, it's platform dependent. On x86, the value must be aligned on a 4 byte boundary. Generally for most platforms, the read must execute in a single CPU instruction.

optimizer caching
The optimizer doesn't know you are reading a value modified by a different thread. declaring the value volatile helps with that: the optimizer will issue a memory read / write for every access, instead of trying to keep the value cached in a register.

CPU cache
Still, you might read a stale value, since on modern architectures you have multiple cores with individual cache that is not kept in sync automatically. You need a read memory barrier, usually a platform-specific instruction.

On Wintel, thread synchronization functions will automatically add a full memory barrier, or you can use the InterlockedXxxx functions.

MSDN: Memory and Synchronization issues, MemoryBarrier Macro

[edit] please also see drhirsch's comments.


You ask a question about reading a variable and later you talk about updating a variable, which implies a read-modify-write operation.

Assuming you really mean the former, the read is safe if it is an atomic operation. For almost all architectures this is true for integers.

There are a few (and rare) exceptions:

  • The read is misaligned, for example accessing a 4-byte int at an odd address. Usually you need to force the compiler with special attributes to do some misalignment.
  • The size of an int is bigger than the natural size of instructions, for example using 16 bit ints on a 8 bit architecture.
  • Some architectures have an artificially limited bus width. I only know of very old and outdated ones, like a 386sx or a 68008.

I'd recommend not to rely on any compiler or architecture in this case.
Whenever you have a mix of readers and writers (as opposed to just readers or just writers) you'd better sync them all. Imagine your code running an artificial heart of someone, you don't really want it to read wrong values, and surely you don't want a power plant in your city go 'boooom' because someone decided not to use that mutex. Save yourself a night-sleep in a long run, sync 'em.
If you only have one thread reading -- you're good to go with just that one mutex, however if you're planning for multiple readers and multiple writers you'd need a sophisticated piece of code to sync that. A nice implementation of read/write lock that would also be 'fair' is yet to be seen by me.


Imagine that you're reading the variable in one thread, that thread gets interrupted while reading and the variable is changed by a writing thread. Now what is the value of the read integer after the reading thread resumes?

Unless reading a variable is an atomic operation, in this case only takes a single (assembly) instruction, you can not ensure that the above situation can not happen. (The variable could be written to memory, and retrieving the value would take more than one instruction)

The consensus is that you should encapsulate/lock all writes individualy, while reads can be executed concurrently with (only) other reads