代码之家  ›  专栏  ›  技术社区  ›  John

用volatile声明并存储在对齐地址上的读写int是否可以保证是原子的?

  •  -1
  • John  · 技术社区  · 4 年前

    这里是相关的 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();
    }
    

    问题 :可以阅读&写入用 volatile 并且存储在一个对齐的地址上,保证是原子的吗?或者结论是正确的 X86 platform ?

    有人告诉我不要使用 不稳定的 .此关键字是在C++具有内存模型之前添加的。它会消除一些问题(通过阻止一些编译器优化),但不是所有问题,而且代码仍然会有UB。

    有人告诉我 it's atomic on any platform .

    我在网上找到了一些帖子,但这些帖子是十多年前更新的。例如:

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

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

    更新 : 根据(这篇帖子)[https://codywu2010.wordpress.com/2014/11/03/is-int-write-operation-atomic-on-x86_64/][^3],上面说:

    我们几乎总是从文档和web帖子中读到X86_64可以原子地执行64位写入操作。 因此,如果线程1将值A写入一个整数,而线程2将值B写入同一个整数,那么我们可以保证观察值A或值B,而不观察两者之间的任何值,当然忽略初始值。

    这些帖子(标有[^1][^2][^3])似乎都说它是原子的。

    现在我真的很困惑。有人能解释一下这件事吗?

    0 回复  |  直到 4 年前