C++ 11标准是否保证std :: atomic <>是作为原子操作实现的?

use*_*710 21 c++ multithreading atomic c++11

我在一个交叉点,我试图在基于互斥锁的数据结构和无锁(可能无等待)的数据结构之间选择一个.

虽然挖掘得更深,但我没有发现C++ 11标准支持原子类型的原子操作这一事实,甚至对于基于宽度的积分也没有atomic_uint32_t.换句话说,它不仅仅是未被授予真正原子的std::atomic<>接口,唯一看起来它被赋予整个标准库中的原子的东西是.std::atomic_flag

这是真的还是我遗失了什么?这是什么原因?我的意思是标准称为"原子"的东西显然根本不是原子的,甚至允许使用互斥锁或阻止呼叫.

Die*_*ühl 12

C++标准不保证std::atomic<T>操作是原子的.但是,您可以使用std::atomic<T>::is_lock_free()以查明是否无std::atomic<T>锁操作29.6.5 [atomics.types.operations.req]第7段:

返回:如果对象的操作是无锁的,则返回true,否则返回false.

如果它不是无锁的,它仍然会执行所需的同步,但它会使用一些锁来执行此操作.

  • 所以我正确地从你的回答中推断出"原子"意味着"在cpu级别不可中断"?如果没有实现其名称的含义,为什么选择"原子"这个名称呢? (5认同)
  • @JohannesSchaub:原子类型的语义是以原子和适当的线程安全的方式进行更改.使用舔的实现就是这样.该方法的另一个方面是不同的硬件支持不同的硬件级原子支持,并且所选择的方法允许实现给定类型可能的最佳方法. (3认同)
  • 我很困惑.我虽然使用锁只是实现原子操作的一种方法(比较使用原子CAS).即使使用锁,它仍然是原子的吗?所以标准不能保证`std :: atomic`提供无锁实现,但它保证提供原子操作? (3认同)
  • Downvoted."原子"并不意味着无锁.无论是使用锁还是原子CPU指令,这些操作都是原子操作.(在前一种情况下,他们将原子性构建为抽象,但它们仍然是原子的) (3认同)
  • @JohannesSchaub-litb - C++ 标准中的“原子”有三个要求:无数据竞争、缓存一致性以及原子操作之间没有代码移动。其他上下文很可能使用“原子”的不同定义,但任何此类其他定义都不适用于 C++ 原子。 (2认同)

Jus*_*Sid 10

如果原子是你的意思,使用没有锁的硬件支持,那么是的,标准并没有给你一个保证.为什么?好吧,因为不同的架构支持不同类型的硬件原子性.std::atomic<>有一个方便的is_lock_free()方法,可以用来检查给定的对象实际上是无锁,或内部使用锁来保证原子操作.您可以使用它并检查您的目标硬件是否无锁,然后决定要采用的数据结构.

然而,话虽如此,如果目标架构对您感兴趣的固定宽度积分的原子操作有硬件支持,并且您没有从贫民窟的阴暗软件商店获得标准库的副本,那么可能打算使用硬件而不是完全锁定.

  • @MarkusKoivisto:对于命名两种类型`std :: atomic <T>`而言,这并不是一个争论.因为你必须两次实现算法,你可以在无锁分支中使用`atomic <T>`,在你执行锁定的分支中使用``T`.真正的问题是,使用当前界面,您必须决定_at run time_选择哪种算法.这不是'constexpr`.更糟糕的是,你必须为每个对象检查它,因为它甚至不是"静态".每个临时工作也必须进行检查. (2认同)