5

If I update a variable in one thread like this: receiveCounter++;

and then from another thread I only ever read this variable and write its value to a GUI.

Is that safe? Or could this instruction be interrupted in the middle so the value in receiveCounter is wrong when it is read by another thread? it must be so right since ++ is not atomic, it is several instructions.

I don't care about synchronizing reads and writes, it just needs to be incremented and then update in the GUI but this does not have to happen directly after each other.

What I care about is that the value cannot be wrong. Like the ++ operation being interrupted in the middle so the read value is completely off.

Do I need to lock this variable? I really do not want to since it is update very often. I could solves this by just posting a message to a MAIN thread and copy the value to a Queue (which then would need to be locked but I would not do this on every update) I guess.

But I am interested in the above problem anyway.

BartoszKP
  • 34,786
  • 15
  • 102
  • 130

6 Answers6

3

If one thread changes the value in a variable and another thread reads that value and the program does not synchronize the accesses it has a data race, and the behavior of the program is undefined. Change the type of receiveCounter to std::atomic<int> (assuming it's an int to begin with)

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
2

At its core it is a read-modify-write operation, they are not atomic. There are some processors around that have a dedicated instruction for it. Like Intel/AMD cores, very common, they have an INC instruction.

While that sounds like that could be atomic, since it is a single instruction, it still isn't. The x86/x64 instruction set doesn't have much to do anymore with the way the execution engine is actually implemented. Which executes RISC-like "micro-ops", the INC instruction is translated to multiple micro-ops. It can be made atomic with the LOCK prefix on the instruction. But compilers don't emit it unless they know that an atomic update is desired.

You will thus need to be explicit about it. The C++11 std::atomic<> standard addition is a good way. Your operating system or compiler will have intrinsics for it, usually named something like "Interlocked" or "__built_in".

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I understood the question as only the read part and write part need to be atomic. Not the entire read-modify-write. Shouldn't that be more of an alignment and data size issue. – adrianm Aug 16 '13 at 11:07
1

Simple answer: NO.

because i++; is the same as i = i + 1;, it contains load, math-operation, and saving the value. so it is in general not atomic.
However the really executed operations depend on the instruction set of the CPU and might be atomic, depending on the CPU architecture. But the default is still not atomic.

Simulant
  • 19,190
  • 8
  • 63
  • 98
  • 1
    Correct answer, wrong reasoning. It can be implemented in a single instruction on some processors. However as the processor isn't specified in the question and as the operation isn't specified to be atomic in the C++ standard it isn't threadsafe. – user207421 Aug 16 '13 at 10:36
0

Generally speaking, it is not thread-safe because the ++ operator consists in one read and one write, the pair of which is not atomic and can be interrupted in between.

Then, it probably also depends on the language/compiler/architecture, but in a typical case the increment operation is probably not thread safe.

(edited)

As for the read and write operations themselves, as long as you are not in 64-bit mode, they should be atomic, so if you don't care about other threads having the value wrong by 1, it may be ok for your case.

Lake
  • 4,072
  • 26
  • 36
  • Not only that, but sometimes it can be *okay* if the result is not correct. For example if the GUI thread is polling the variable, it might be okay to have the wrong value for a fraction of a second. – Some programmer dude Aug 16 '13 at 08:36
  • Indeed @JoachimPileborg. In hte case of progress counters/bars, and the like, updated on a timer every second, the values seen are always going to be out-of-date to some extent anyway, so why bother about an occasional hiccup? On many processors, the ++ will end up a a single-instruction INC anyway. – Martin James Aug 16 '13 at 11:06
0

++ is equivalent to i=i+1.

++ is not an atomic operation so its NOT thread safe. Only read and write of primitive variables (except long and double) are atomic and hence thread safe.

rai.skumar
  • 10,309
  • 6
  • 39
  • 55
0

No. Increment operation is not atomic, hence not thread-safe.

In your case it is safe to use this operation if you don't care about its value in specific time (if you only read this variable from another thread and not trying to write to it). It will eventually increment receiveCounter's value, you just don't have any guarantees about operations order.

GuardianX
  • 515
  • 11
  • 29