自旋锁——代码在循环中“自旋”。
自旋锁(spin lock)是一种非阻塞锁,如果某线程需要获取锁,但该锁已经被其他线程占用时,该线程不会被挂起,而是在不断的消耗 CPU 的时间,不停的试图获取锁。
互斥量(mutex)是阻塞锁,当某线程无法获取锁时,该线程会被直接挂起,该线程不再消耗CPU时间,当其他线程释放锁后,操作系统会激活那个被挂起的线程,让其投入运行。
因此,多核 CPU 才能用自旋锁。
其他细节,详看下面代码注释。
#ifndef AMYSPINLOCK_H
#define AMYSPINLOCK_H
#include <atomic>
// 采用 std::atomic_flag 实现自旋锁互斥,即 TAS 算法(Test And Set)
class AMySpinLock1
{
public:
AMySpinLock1() = default;
AMySpinLock1(const AMySpinLock1&) = delete;
AMySpinLock1& operator=(const AMySpinLock1&) = delete;
void lock()
{
while(flag.test_and_set(std::memory_order_acquire));
}
void unlock()
{
flag.clear(std::memory_order_release);
}
private:
// std::atomic_flag 类型的对象必须由宏 ATOMIC_FLAG_INIT 初始化,它把标志初始化为置零状态。
std::atomic_flag flag{ATOMIC_FLAG_INIT};
};
// 采用 std::atomic<bool> 和 compare_exchange_strong 实现自旋锁互斥,即 CAS 算法(Compare And Swap)
// 比较-交换操作是原子类型的编程基石。
//

本文详细解析了自旋锁(如std::atomic_flag的TAS和std::atomic<bool>的CAS算法)与互斥量的差异,强调了自旋锁在多核CPU环境下的优势,并通过代码实例展示了如何使用std::atomic实现自旋锁。
最低0.47元/天 解锁文章
996

被折叠的 条评论
为什么被折叠?



