C++ std::atomic_flag实现自旋锁

一、原子操作

原子操作就是在多线程程序中“最小的且不可并行化的”操作,就是说多个线程访问同一个资源时,有且仅有一个线程能对资源进行操作。

在C++11之前,使用第三方API可以实现并行编程,比如pthread多线程库,但是在使用时需要创建互斥锁,以及进行加锁、解锁等操作来保证多线程对临界资源的原子操作,这无疑增加了开发的工作量。不过从C++11开始,C++从语言层面开始支持并行编程,内容包括了管理线程、保护共享数据、线程间的同步操作、低级原子操作等各种类。新标准极大地提高了程序的可移植性,以前的多线程依赖于具体的平台,而现在有了统一的接口。

std::atomic_flag是最简单的标准原子类型,他代表一个布尔标识,没有拷贝构造函数和拷贝赋值运算符(=delete)。原子类型指的是对它的单个操作一定要在一个指令周期完成。

二、std::atomic_flag 构造函数

atomic_flag() noexcept = default;
atomic_flag (const atomic_flag&T) = delete;


std::atomic_flag 只有默认构造函数,拷贝构造函数已被禁用,因此不能从其他的 std::atomic_flag 对象构造一个新的 std::atomic_flag 对象。

如果在初始化时没有明确使用 ATOMIC_FLAG_INIT初始化,那么新创建的 std::atomic_flag 对象的状态是未指定的(unspecified)(既没有被 set 也没有被 clear。)另外,atomic_flag不能被拷贝,也不能 move 赋值。

ATOMIC_FLAG_INIT: 如果某个 std::atomic_flag 对象使用该宏初始化,那么可以保证该 std::atomic_flag 对象在创建时处于 clear 状态。

三、atomic_flag只能有3个状态:

  • 未设置(定义时未初始化,在c++20以后在定义时自动初始化为false,即在c++20以后此状态不再存在)
  • 清除(false)
  • 设置(true)

四、std::atomic_flag::test_and_set 


 函数原型如下:

bool test_and_set(std::memory_order order = std::memory_order_seq_cst) volatile noexcept;	(1)	(since C++11)
bool test_and_set(std::memory_order order = std::memory_order_seq_cst) noexcept;	(2)	(since C++11)


test_and_set() 函数检查 std::atomic_flag 标志,如果 std::atomic_flag 之前没有被设置过,则设置 std::atomic_flag 的标志,并返回先前该 std::atomic_flag 对象是否被设置过,如果之前 std::atomic_flag 对象已被设置,则返回 true,否则返回 false。
 

无、自旋锁实现示例

class spin_mutex {
  std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
  spin_mutex() = default;
  spin_mutex(const spin_mutex&) = delete;
  spin_mutex& operator= (const spin_mutex&) = delete;
  void lock() {
    while(flag.test_and_set(std::memory_order_acquire))
      ;
  }
  void unlock() {
    flag.clear(std::memory_order_release);
  }
};

memory_order_acquire, memory_order_release是用来指定内存序。从代码中可以看到,如果flag已经被其它线程设置,那么就相当于自旋锁已经被其它线程占有,那么就会一直while循环检查flag,直到其它线程释放flag

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ze言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值