I am writing in Visual Studio 2013. There is, therefore, a function that should be executed in the stream:

void click(int &a, int &flag){ do{ a = _getch(); } while (flag != 0); } 

And there is a main function in which a thread is declared (thread class) and when you click on the keyboard, the button code is displayed.

 int keyState = 0; void main() { int fl = 1; thread input(click, ref(keyState), ref(fl)); while (true){ while (keyState == 0){} cout << keyState << endl; keyState = 0; } system("pause"); 

}

While I collect in Debug, then everything goes fine, but it is worthwhile to build the project in Release, as the whole program does not work. The reason in line

 while (keyState == 0){} 

It is worth adding any output to the loop body.

 while (keyState == 0){ cout << ""; } 

how everything starts to work. Me as a beginner (2nd year uni), it just leads to a stupor. What is the reason?

    1 answer 1

    The compiler does not "see" that this variable may change in another thread.
    In Release mode, a more rigid optimization is turned on and the check is discarded as unnecessary (the value does not change ...).

    It is necessary to “tell” the compiler to read it from the main memory each time.

    The main ways are using volatile and (which seems to me more correct) std :: atomic

    std::atomic usage example

     #include <atomic> //... std::atomic<int> keyState(0); //В 1м потоке while(keyState.load()==0) {} // 2й поток if (some) { keyState.store(new_value); } 
    • Thanks for the answer. It only remains unclear why the check is still being conducted if console output is used in the body of the loop. For any other operations, the program is worth it. Is the output stream feature? - Mikhail Vilisov
    • There may be a situation that if there is no code in the loop, the value is taken from the processor cache (that is, the code does not see changes in RAM), and if there is a code, the cache is updated and the changes become visible. PS course on parallel programming , I advise - Maxim Timakov
    • five
      atomic and volatile are, in general, completely different things. In this case, it should be declared exactly as volatile - the fact that the variable can be changed in some way not known to the compiler is important here. As far as the proposed method with polling in a cycle is bad, this is a topic for a separate conversation ... In the literature, Meyers strongly insists on not confusing atomic and volatile . - Harry