2

I have a UDP thread which is maintaining an int variable '__counter' of number of packets arrived , and a manger thread which needs to read this __counter variable and just print it on the log file.

Im not required for timely update reads means I am allowed to get old or new __counter variable. Its just printing it on logs.

For this "_counter" shared variable which is of type uint_32 , do I need to wrap it inside std::atomic<> ?

Can I use it as a normal variable and share it between threads because I dont need timely read? Do I need to care about cache sizes or something ?

RishiN
  • 39
  • 5
  • 3
    Yes, you have to wrap it into atomic or use another memory synchronisation routine. Otherwise it is a data race and UB. With all the heavy operations that UDP uses, maintaining a single atomic int with relaxed memory instructions should be the last of your worries. – ALX23z Oct 15 '21 at 05:31
  • But would normal variable cause problem ? _counter is uint32 variable and lets suppose cache size is 64 . So for such scenario still I need std::atomic ? I dont care if one thread is undating it, same time another thread reads it and gets an old value. – RishiN Oct 15 '21 at 05:43
  • 2
    Have you read questions like [Are C++ Reads and Writes of an int Atomic?](https://stackoverflow.com/q/54188/7143595) – MatG Oct 15 '21 at 06:03
  • 2
    @RishinN yes it can obviously cause problems. For instance, the thread that logs out the result might optimize out any readings of the variable and just print out the same data it read once in the beginning. Or the UDP thread might never bother to update the new value to RAM or any shared cache. Or any other nonsense that might happen with UB lurking around. – ALX23z Oct 15 '21 at 07:26
  • 2
    You have a data race which is UB. But also think what the optimiser will make of the code. On the reading thread - no updates to `__counter` so the optimiser can remove all reads but the 1st, so `__counter` never appears to change. On the writing thread - no code reads `__counter` so the write can be optimised out completely. – Richard Critten Oct 15 '21 at 07:53
  • @MatG: Unfortunately that is a very old question and most of the answers are obsolete. Prior to C++11, the Standard said nothing about multithreading or atomicity, so you were left to reason about the actual behavior of specific compilers and the question was hard to answer. Since C++11 there is a very easy answer: **yes, `std::atomic` is required**, no ifs ands or buts. Unsynchronized access to plain `uint32_t` is a data race and causes undefined behavior. – Nate Eldredge Oct 16 '21 at 17:30
  • Does this answer your question? [Are C/C++ fundamental types atomic?](https://stackoverflow.com/questions/35226128/are-c-c-fundamental-types-atomic) – Nate Eldredge Oct 16 '21 at 17:32
  • (It might actually have been C++03 instead of C++11. I think I am mixing it up with C11 which is when C got atomics.) – Nate Eldredge Oct 16 '21 at 17:36

0 Answers0