当我们谈论原子变量时,比如C++11的
atomic<>
,它是无锁的吗?还是无锁性是另一回事?如果我使用原子变量管理队列,它会比无锁队列慢吗?atomic<>
,它是无锁的吗?还是无锁性是另一回事?如果我使用原子变量管理队列,它会比无锁队列慢吗?atomic<T>
对象可能会使用互斥锁来实现,这将不是无锁的。在这种情况下,任何使用这些对象的容器都不是无锁的。atomic<T>
变量是否为无锁的方法:您可以使用var.is_lock_free()
或atomic_is_lock_free(&var)
。这些函数保证在给定程序执行期间始终为相同类型的T
返回相同的值。对于基本类型,如int
,还提供了宏(例如ATOMIC_INT_LOCK_FREE
),用于指定是否可用无锁原子访问该类型。atomic<T>
对于所有大小的 T
都可能不是本地原子的?我无法想象一个没有真正本地原子操作的平台如何首先实现互斥量... - Uselessstd::atomic<char>
这样的东西是无锁的。但是,如果 32 位整数通过进行 4 个字节操作来模拟,则这不是原子的。所以大多数情况下 std::atomic<int>
不会是无锁的。然而,你可以使用字节原子操作来创建互斥量(例如自旋锁)。 - KillianDSstd::atomic_flag
(必须是无锁的),但不能用于一般的原子操作(因为它不能进行简单的加载)。 - Anthony Williams无锁通常应用于多个线程共享的数据结构,其中同步机制不是互斥的;意图是所有线程都应该保持某种形式的进展,而不是在互斥量上睡眠。
atomic<T>
变量不使用锁(至少在您的平台上T
本地原子时),但它们在上述意义上不是无锁的。您可能会在无锁容器的实现中使用它们,但它们本身并不足够。
例如,atomic<queue<T>>
不会突然将普通的std::queue
变成无锁数据结构。不过您可以实现一个真正无锁的atomic_queue<T>
,其成员为atomic
。
请注意,即使atomic<int>
在您的平台上本地原子且没有使用锁进行仿真,这也不会以任何有趣的方式使其成为无锁。在此意义上,纯int
已经是无锁的: atomic<>
包装器可为您提供显式的内存顺序控制和访问硬件同步原语。
int
在只有一个写入者的情况下是线程安全的,例如,如果读取者对其视图的实时性要求不高,则可以完全线程安全地使用普通的int
来处理某些应用程序逻辑。 - Uselessinc [x]
可能具有原子加载和原子存储,但在这两者之间内存可能会发生变化)。 - Leeor