std :: atomic和std :: mutex之间的区别

Yve*_*ves 4 multithreading mutex thread-safety c++11 stdatomic

如何使用std :: atomic <>

在上面的问题中,显然我们可以std::mutex用来保持线程安全.我想知道何时使用哪一个.

classs A
{
    std::atomic<int> x;

public:
    A()
    {
        x=0;
    }

    void Add()
    {
        x++;
    }

    void Sub()
    {
        x--;
    }     
};
Run Code Online (Sandbox Code Playgroud)

std::mutex mtx;
classs A
{
    int x;

public:
    A()
    {
        x=0;
    }

    void Add()
    {
        std::lock_guard<std::mutex> guard(mtx);
        x++;
    }

    void Sub()
    {
        std::lock_guard<std::mutex> guard(mtx);
        x--;
    }     
};
Run Code Online (Sandbox Code Playgroud)

Bat*_*eba 5

根据经验,std::atomic用于POD类型,其中底层专业化将能够使用巧妙的东西,如CPU上的总线锁(这将不会给您带来管道转储的开销),甚至是自旋锁.在某些系统上,int可能已经是原子的,因此std::atomic<int>将有效地专门化为int.

使用std::mutex用于非POD类型,铭记获取互斥是至少比一个总线锁定慢一个数量级.

如果您仍然不确定,请测量性能.

  • `std::atomic&lt;small_struct&gt;` *可能*对于适合 16 字节的对象很有用,但前提是您*确切*知道您在做什么,并且目标平台是您知道具有 x86-64 之类的平台`lock cmpxchg16b`,然后使用 `-mcx16` 进行构建(不幸的是,由于 cmpxchg16b 是一个扩展,它不是基线 x86-64 的一部分,因为第一代 AMD64 CPU 中缺少它。)请参阅[我的答案](http: //stackoverflow.com/questions/38984153/implement-aba-counter-with-c11-cas)关于两个指针大小的对象上的比较和交换。 (3认同)
  • `int` 加载和 `int` 存储通常是原子的(例如它们在 x86 上),但是 [`my_int++` 在多核系统上从不是原子的](http://stackoverflow.com/questions/39393850/can-num -be-atomic-for-int-num/39396999#39396999)。我同意你的总体观点,即 std::atomic 原始类型可能很有用,而其他任何事情都可能只是在幕后进行效率较低的锁定。 (2认同)