0

If there is only read-write conflict on an integer, i.e., some threads are reading but only one thread is writing. There's no write-write conflict.

Furthermore, there's no ordering requirements. That is to say, even atomic variables are used, memory_order_relaxed is enough for all reading and writing.

In this case, is atomic variable a must? If I just use a volatile integer, will there be any potential harms?

To give an example, let's say we have a ring buffer, and there are only two threads accessing this ring buffer. One consumer thread (will write to consumer_index, and read from producer_index), and one producer thread (will write to producer_index, and read from consumer_index).

We have to let producer index be atomic, i.e.,

std::atomic<size_t> producer_index;

This is because, when the consumer thread sees the producer_index is advanced, consumer will assume that the content on the ring buffer must be ready to consume (the producer must have pushed the data already). So there's some ordering here.

However, the consumer index is different. When the producer thread sees that the consumer_index is advanced, it doesn't need to know anything about the ring buffer, it can safely re-use that space. The consumer thread must have popped this data and saved to somewhere else and the producer need not to care about where it is saved.

So I don't see the need to make consumer_index as atomic here. Is a volatile enough for this consumer_index?

volatile size_t consumer_index;

I hope I explained the situation clearly. Thanks.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user534498
  • 3,926
  • 5
  • 27
  • 52
  • 1
    Your first paragraph contradicts itself. You say you have multiple readers and one writer for a shared variable, but then say you have *no* read/write conflict. In C++ that's data-race UB for a plain or `volatile` object. The ISO C++ standard only guarantees anything if that object is `std::atomic`, or if you use a mutex or other synchronization to make sure writes can't happen while readers are reading. Or do you mean something other than "data race UB" when you say "read/write conflict"? – Peter Cordes May 30 '20 at 03:54
  • 1
    Anyway, if you think you want `volatile` instead of `std::atomic` to make your code faster, what you actually want is `std::atomic` with `memory_order_relaxed`. (And avoiding atomic RMWs, e.g. `x.store(x.load(relaxed) + 1, relaxed)` instead of `x++`); [When to use volatile with multi threading?](https://stackoverflow.com/a/58535118) - basically never, certainly not for `int`. – Peter Cordes May 30 '20 at 03:56
  • Closing as a duplicate because this looks like exactly what my linked answer is answering. I didn't read every word of this question, let me know if I misjudged and that wasn't what you were looking for. – Peter Cordes May 30 '20 at 03:58
  • Pls explain **why** you want to avoid a tool you *feel* might solve your problem (here: atomic) and how another tool (here: volatile) would solve it "better" (better how?). – curiousguy May 30 '20 at 09:39

0 Answers0