来自 C++ Concurrency in Action:
std::atomic 和 std::atomic_flag 之间的区别在于 std::atomic 可能不是无锁的;实现可能必须在内部获取互斥锁以确保操作的原子性
我想知道为什么。如果 atomic_flag 保证是无锁的,为什么不保证它atomic<bool>
也是如此?这是因为成员函数compare_exchange_weak
吗?我知道有些机器缺少一个比较和交换指令,是这个原因吗?
来自 C++ Concurrency in Action:
std::atomic 和 std::atomic_flag 之间的区别在于 std::atomic 可能不是无锁的;实现可能必须在内部获取互斥锁以确保操作的原子性
我想知道为什么。如果 atomic_flag 保证是无锁的,为什么不保证它atomic<bool>
也是如此?这是因为成员函数compare_exchange_weak
吗?我知道有些机器缺少一个比较和交换指令,是这个原因吗?
首先,您完全可以拥有类似 的东西std::atomic<very_nontrivial_large_structure>
,因此std::atomic
通常不能保证这样的东西是无锁的(尽管在大多数系统上,大多数琐碎类型的特化都像bool
或int
可能可以)。但这有点无关。
atomic_flag
N2427 /29.3 的注释中给出了为什么必须是无锁的确切原因:
因此,这些操作必须是无地址的。没有其他类型需要无锁操作,因此 atomic_flag 类型是符合此标准所需的最小硬件实现类型。剩下的类型可以用 atomic_flag 来模拟,尽管属性不太理想。
换句话说,这是每个平台上必须保证的最低限度的东西,因此可以正确实施标准。
该标准不保证原子对象是无锁的。在不为 type 提供无锁原子操作的平台上,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
不需要使用互斥锁或其他同步方式。