1

Here the related code snippet:

#include <functional>
#include <thread>
#include <iostream>
#include <chrono>
#include <atomic>

#ifdef NO_STUCK_WITH_OPTIMIZATION 
using TYPE = std::atomic<int>;
#else
using TYPE = volatile int;  //The progrom seems not get stuck if the optimization is enabled.
#endif

int main()
{
    TYPE is_run{1}; //If the is_run is declared as volatile, then the program would never get stuck?
    auto thread = std::thread([&is_run](){while(1==is_run){
                                        }
        std::cout << "thread game over" << std::endl;
    });

    is_run = 0;
    thread.join();
}

Question: Could reading & writing int which is declared with volatile and stored on a aligned address be garanteed to be atomic? Or the conclusion is right just on X86 platform?

Somebody told me not to use volatile. This keyword was added before C++ had a memory model. It will make some issues go away (by preventing some compiler optimization), but not all and your code would still have UB.

And somebody told me that it's atomic on any platform.

I found some posts on SO, but the posts were updated more than 10 years ago. For example:

ARM: Is writing/reading from int atomic?. [^1]

Are C++ Reads and Writes of an int Atomic?. [^2]

UPDATED: And as per (this post)[https://codywu2010.wordpress.com/2014/11/03/is-int-write-operation-atomic-on-x86_64/] [^3], which says that:

Nearly always we read from documents and web posts that X86_64 can do 64bits write operation atomically. So if thread 1 is writing value A to an integer while thread 2 is writing value B to the same integer we are guaranteed to observe either value A or value B and never anything in between, ignoring initial value of course.

It seems that the posts (marked with [^1] [^2] [^3]) all says that it's atomic.

And now I am really confused now.Could somebody shed some light on this matter?

John
  • 2,963
  • 11
  • 33
  • 4
    The person who told you to avoid `volatile` for dealing with multithreading issues was correct -- the semantics of `volatile` aren't sufficiently strong to be useful for atomic operations. If you want atomic integers in C++, `std::atomic` is the correct tool for the job. – Jeremy Friesner Apr 04 '22 at 03:01
  • 4
    `volatile` does not ensure synchronization between threads. It only treats the (single thread) access of that variable as a visible side effect for purposes of optimization. – JohnFilleau Apr 04 '22 at 03:02
  • @JohnFilleau If the side effect of the variable is guaranteed to be seen by the other thread, it does not mean reading&writing is atomic? Why? Could you please explain that in more details for me? – John Apr 04 '22 at 03:07
  • 2
    @John `volatile` doesn't protect the memory. If two threads write to a volatile variable, that is a data race and undefined behavior. The standard requires you use a synchronization technique, and `volatile` is not amongst those techniques. – NathanOliver Apr 04 '22 at 03:10
  • Does this answer your question? [Why the code snippet gets stuck when optimization is enabled?](https://stackoverflow.com/questions/71726178/why-the-code-snippet-gets-stuck-when-optimization-is-enabled) – Jeffrey Apr 04 '22 at 03:12
  • 1
    Every book on threading in c++ tells you how to do what you want. And they all say that volatile doesn't do what you want. So just follow the instructions from the experts. – xaxxon Apr 04 '22 at 03:12
  • 1
    "Could reading & writing int which is declared with volatile and stored on a aligned address be guaranteed to be atomic?" --> No. To guarantee atomic access, qualify with `atomic` or prohibit interruption of the process/thread with implementation specific code. – chux - Reinstate Monica Apr 04 '22 at 03:16
  • @John everybody told you to stay clear of `volatile`. It's also in the comments of your first question. I realize there's difference between the two, but for a Q&A site like SO, we must be very crisp and concise. Your edit to the 1st question was the right way to go. A second question is too much. – Jeffrey Apr 04 '22 at 03:19
  • @ NathanOliver Thank you. Please see the updated question. – John Apr 04 '22 at 03:19
  • @John there's also a communication issue. The three questions you linked use the wording "atomic" but they don't refer to `std::atomic`, I think that feeds your confusion – Jeffrey Apr 04 '22 at 03:21
  • @Jeffrey How do you understand the wording "atomic" in the aforementioned posts? My mother language is not English. – John Apr 04 '22 at 03:25
  • @John they mean atomic in the architecture / processor sense -- an action that cannot be preempted. – JohnFilleau Apr 04 '22 at 12:40

0 Answers0