为什么启用优化后代码片段会卡住?

Why the code snippet gets stuck when optimization is enabled?

下面的代码片段有3个问题。

  1. 当宏(即NO_STUCK_WITH_OPTIMIZATION )未启用时,为什么this code snippet在启用优化(即-O1-O2或[=14时卡住=]) 而如果未启用优化,程序运行良好?
  2. 为什么加了std::this_thread::sleep_for()程序就不会卡了?

已更新: 3、如果is_run声明为volatile(详见the code snippet), then the program would never get stuck on X86? ^^更新结束^^

    #include <functional>
    #include <thread>
    #include <iostream>
    #include <chrono>
    #include <atomic>
    
    #ifdef NO_STUCK_WITH_OPTIMIZATION 
    using TYPE = std::atomic<int>;
    #else
    using TYPE = int;  //The progrom gets stuck if the optimization is enabled.
    #endif
    
    int main()
    {
        TYPE is_run{1};
        auto thread = std::thread([&is_run](){while(1==is_run){
              //std::this_thread::sleep_for(std::chrono::milliseconds(10)); //If this line is added, the program is no longer gets stuck. Why?
                                            }
            std::cout << "thread game over" << std::endl;
        });
    
        std::this_thread::sleep_for(std::chrono::seconds(1));
        is_run = 0;
        thread.join();
    }

您有一个 multi-threaded 程序。一个线程执行 is_run = 0;.

另一个线程执行 while(1==is_run)。虽然你保证睡眠(另一个问题),写在读之前完成,你需要告诉编译器同步这个变量。

在 C++ 中,确保一个线程看到更改的简单方法是使用 atomic<int>。如果您不这样做,其他线程可能永远看不到更改。这种更改的隐藏可能是由于编译时代码的局部优化,OS 决定不刷新某些内存页面或硬件本身决定不需要重新加载内存。

放置原子变量可以保证所有这些系统都知道你想做什么。所以,使用它。 :-)

摘自评论:

https://en.cppreference.com/w/cpp/language/memory_model#Threads_and_data_races

A program that has two conflicting evaluations has a data race unless both evaluations execute on the same thread or in the same signal handler, or both conflicting evaluations are atomic operations (see std::atomic), or one of the conflicting evaluations happens-before another (see std::memory_order) If a data race occurs, the behavior of the program is undefined.