来自C ++并发行动:
std :: atomic和std :: atomic_flag之间的区别是std :: atomic可能不是无锁的;实现可能必须在内部获取互斥锁,以确保操作的原子性
我想知道为什么。如果保证atomic_flag无锁,为什么atomic<bool>
也不能保证?
这是因为成员函数compare_exchange_weak
吗?我知道有些机器缺少单一的比较和交换指令,原因是什么?
答案 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
类型,不需要使用互斥或其他方式进行同步。