为什么只保证std :: atomic_flag无锁?

时间:2015-05-15 09:54:32

标签: multithreading c++11 atomic stdatomic

来自C ++并发行动:

  std :: atomic和std :: atomic_flag之间的区别是std :: atomic可能不是无锁的;实现可能必须在内部获取互斥锁,以确保操作的原子性

我想知道为什么。如果保证atomic_flag无锁,为什么atomic<bool>也不能保证? 这是因为成员函数compare_exchange_weak吗?我知道有些机器缺少单一的比较和交换指令,原因是什么?

2 个答案:

答案 0 :(得分:5)

首先,完全允许您使用std::atomic<very_nontrivial_large_structure>之类的内容,因此std::atomic通常无法保证无锁定(尽管大多数特殊类型都适用于bool或者int可能在大多数系统上都可以。但这有些不相关。

N2427 / 29.3中的注释中给出了为什么atomic_flag而其他必须无锁的确切原因:

  

因此,操作必须是无地址的。没有其他类型需要无锁操作,因此atomic_flag类型符合所需的最低硬件实现类型。 其余类型可以使用atomic_flag 进行模拟,但属性不够理想。

换句话说,它是每个平台必须保证的最小限度,因此可以正确实施标准。

答案 1 :(得分:1)

标准不保证原子对象是无锁的。在不为类型T提供无锁原子操作的平台上,std::atomic<T>对象可以使用互斥锁来实现,该互斥锁不会无锁。在这种情况下,在其实现中使用这些对象的任何容器也不会是无锁的。

标准提供了检查std::atomic<T>变量是否无锁的机会:您可以使用var.is_lock_free()atomic_is_lock_free(&var)。对于诸如int之类的基本类型,还提供了宏(例如ATOMIC_INT_LOCK_FREE),它指定了对该类型的无锁原子访问是否可用。

std::atomic_flag是一种原子布尔类型。几乎总是boolean类型,不需要使用互斥或​​其他方式进行同步。