标准的 atomic bool 和 atomic flag 之间的区别

Posted

技术标签:

【中文标题】标准的 atomic bool 和 atomic flag 之间的区别【英文标题】:difference between standard's atomic bool and atomic flag 【发布时间】:2017-01-12 17:58:14 【问题描述】:

我不知道std::atomic 变量,但知道标准提供的std::mutex(很奇怪!);但是有一件事引起了我的注意:标准提供了两种看似相同(对我而言)的原子类型,如下所列:

    std::atomic<bool>

    std::atomic_flag

std::atomic_flag 包含以下解释:

std::atomic_flag 是一个原子布尔类型。与std::atomic 的所有特化不同,它保证是无锁的。与std::atomic<bool> 不同,std::atomic_flag 不提供加载或存储操作。

我无法理解。 std::atomic<bool> 不保证是无锁的吗?那么它不是原子的还是什么?

那么这两者有什么区别,什么时候该用哪个呢?

【问题讨论】:

“原子”和“无锁”不是同义词。您可以轻松地实现无锁而不是原子的(当您不进行任何同步时会发生这种情况,例如 :P),并且您可以轻松地进行非无锁的原子操作(例如,使用监视器)。 【参考方案1】:

std::atomic<T> 保证对变量的访问是原子的。然而,它并没有说明原子性是如何实现的。它可以使用无锁变量,也可以使用锁。实际实现取决于您的目标架构和类型T

另一方面,std::atomic_flag 保证使用无锁技术实现。

【讨论】:

【参考方案2】:

std::atomic bool 类型不保证是无锁的?

正确。 std::atomic 可以使用锁来实现。

那么它不是原子的还是什么?

std::atomic 是原子的,无论是否使用锁实现。 std::atomic_flag 保证在不使用锁的情况下实现。

那么黑白两个有什么区别

除了无锁保证之外的主要区别是:

std::atomic_flag 不提供加载或存储操作。


什么时候应该使用哪个?

通常,当您需要一个原子布尔变量时,您会想要使用std::atomic<bool>std::atomic_flag 是一个低级结构,可用于实现自定义原子结构。

【讨论】:

如果目标架构支持原子操作,就没有理由使用锁。但如果没有,我想知道 如何 std::atomic_flag 会被实施? @RustyX:所有现有架构都至少支持原子加载和设置字(或等效的否定加载和清除字),这足以实现std::atomic_flag,但不多更多的。请参阅 PA-RISC,其中ldcw 是唯一的原子 RMW 操作。 @RustyX:假设它不能,那就是它的结束。但正如 Fanael 所说,这在现实中不是问题。 @RustyX 实际上,您不需要硬件支持来提供无锁原子性 - 有算法可以安全地做到这一点。然而,首先使用无锁代码的主要原因之一是为了提高内容丰富的数据/代码的性能——这些算法比锁要慢得多。 std::atomic 根据您正在编译的架构为您做出选择。 std::atomic_flag 是“我完全,绝对需要无锁,无论花费多少”。 @Luaan:您需要无锁原子来进行信号处理,因为您不能使用锁来保护与信号处理程序共享的状态而不冒自死锁的风险。

以上是关于标准的 atomic bool 和 atomic flag 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候真的需要使用 atomic<bool> 而不是 bool? [复制]

我需要 std::atomic<bool> 还是 POD bool 足够好?

分配是不是等同于 std::atomic<bool> 的加载/存储

ARM 上的 std::atomic<bool> 无锁不一致(树莓派 3)

C++ tbb::atomic<bool> 声明读取重新赋值

cpp multi thread sync via std::atomic<bool;