std :: atomic_flag不提供加载或存储操作的任何缺点? (自旋锁示例)

时间:2018-08-29 07:05:58

标签: c++ c++11 atomic stdatomic

std::atomic_flagstd::atomic_bool(又名std::atomic<bool>)进行比较,在我看来std::atomic_flag的界面更简单。它仅提供测试,设置和清除标志,而std::atomic_bool还为多个运算符提供重载。

我的一个问题是关于术语:“装载或存储操作”是什么意思?这是否意味着无法任意读取和修改std::atomic_flag的值?

此外,我想知道,std::atomic_bool在用于自旋锁时会更快吗?在我看来,std::atomic_flag在自旋锁期间始终必须读写:

while (my_atomic_flag.test_and_set()); // spin-lock

std::atomic_bool只需执行读取操作(假设原子布尔实现为无锁):

while (my_atomic_bool); // spin-lock

std::atomic_flag严格比std::atomic_bool更有效率吗?还是相反?自旋锁应使用什么?

1 个答案:

答案 0 :(得分:2)

  

“加载或存储操作”是什么意思?这是否意味着无法任意读取和修改std :: atomic_flag的值?

std::atomic_flag不支持正常的存储/加载操作。
它是只能修改的类型。即。您必须执行修改操作才能读取std::atomic_flag对象。
通常,std::atomic_flag是其他操作的基础。它的界面故意简单;它是唯一保证原子无锁操作的原子类型。 它支持的操作是:

std::atomic_flag::clear()
std::atomic_flag::test_and_set()

有了它,您可以轻松构建自己的自旋锁(尽管通常不建议这样做):

class my_spinlock {
    std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:

    void lock()
    {
        while(flag.test_and_set());
    }

    void unlock()
    {
        flag.clear();
    }
};
  

此外,我想知道,std :: atomic_bool用于自旋锁时会更快吗?在我看来,在自旋锁定期间,std :: atomic_flag始终必须读取和写入

好吧,自旋锁总是在获取锁时必须修改其状态。你根本无法不告诉别人就锁住。
基于lock()的{​​{1}}的实现看起来非常相似:

std::atomic<bool>

基于while (flag.exchange(true)); 的自旋锁是否更快?
在我的平台上,两种类型的编译器都会发出相同的程序集,因此我会感到非常惊讶。