我现在面临选择一个互斥锁数据结构或无锁(可能是无等待)数据结构的抉择。
进一步调查后,我发现C++11标准是否支持原子类型的无锁操作都没有明确说明,甚至连像atomic_uint32_t
这样的基于宽度的整数也不支持。换句话说,不仅std::atomic<>
接口不能保证无锁;在整个标准库中唯一可以保证无锁的就是std::atomic_flag
。
这是真的吗?还是我漏掉了什么?这是什么原因呢?我的意思是,标准将“原子”称为显然不是无锁的东西,并且即使允许在幕后使用互斥锁或阻塞调用。
我现在面临选择一个互斥锁数据结构或无锁(可能是无等待)数据结构的抉择。
进一步调查后,我发现C++11标准是否支持原子类型的无锁操作都没有明确说明,甚至连像atomic_uint32_t
这样的基于宽度的整数也不支持。换句话说,不仅std::atomic<>
接口不能保证无锁;在整个标准库中唯一可以保证无锁的就是std::atomic_flag
。
这是真的吗?还是我漏掉了什么?这是什么原因呢?我的意思是,标准将“原子”称为显然不是无锁的东西,并且即使允许在幕后使用互斥锁或阻塞调用。
C++标准并不保证std::atomic<T>
操作是无锁的。但是您可以使用std::atomic<T>::is_lock_free()
来查看std::atomic<T>
的操作是否是无锁的。依据29.6.5 [atomics.types.operations.req]的第7段:
返回:如果对象的操作是无锁的,则为true,否则为false。
如果它不是无锁的,它仍然会执行所需的同步,但是会使用一些锁来实现。
std::atomic
提供无锁实现,但保证提供原子操作是正确的吗? - Bryan Chenis_lock_free()
的方法并不能解决任何问题,锁定和无锁算法以及数据结构是两个完全不同的世界,具有完全不同的检查和平衡。我无法想象一个C++专家会说“好吧,我们将std::atomic<>描述为“可能是原子性的”,但我们还提供了一种方法来检查它是否是无锁的”,从商业角度来看,这根本没有意义,甚至命名也没有多大意义。 - user2485710std::atomic<T>
的理由。既然你必须实现两次算法,那么在无锁分支中可以使用atomic<T>
,而在需要锁定的分支中可以使用普通的T
。真正的问题在于当前接口需要在运行时决定选择哪个算法。它不是constexpr
。更糟糕的是,你必须为每个对象检查它,因为它甚至不是static
。每个临时对象也必须进行检查。 - MSaltersatomic<T>
中添加了一个名为is_always_lock_free
的static constexpr bool
变量,因此如果它不是,则可以使用static_assert
。 - Nicol Bolas
atomic_flag
是唯一保证无锁的。 - Casey