5.2.2 std::atomic_flag的相关操作

std::atomic_flag 是最简单的标准原子类型,它表示了一个布尔标志。这个类型的对象可以在两个状态间切换:设置和清除。它就是那么的简单,只作为一个构建块存在。我从未期待这个类型被使用,除非在十分特别的情况下。正因如此,它将作为讨论其他原子类型的起点,因为它会展示一些原子类型使用的通用策略。

std::atomic_flag 类型的对象必须被ATOMIC_FLAG_INIT初始化。初始化标志位是“清除”状态。这里没得选择;这个标志总是初始化为“清除”:

std::atomic_flag f = ATOMIC_FLAG_INIT;

这适用于任何对象的声明,并且可在任意范围内。它是唯一需要以如此特殊的方式初始化的原子类型,但它也是唯一保证无锁的类型。如果 std::atomic_flag 是静态存储的,那么就得保证其是静态初始化的,也就意味着没有初始化顺序问题;在首次使用时,其都需要初始化。

当你的标志对象已初始化,那么你只能做三件事情:销毁,清除或设置(查询之前的值)。这些事情对应的函数分别是:clear()成员函数,和test_and_set()成员函数。clear()和 test_and_set()成员函数可以指定好内存顺序。clear()是一个存储操作,所以不能有memory_order_acquire或memory_order_acq_rel语义,但是test_and_set()是一个“读-改- 写”操作,所有可以应用于任何内存顺序标签。每一个原子操作,默认的内存顺序都是 memory_order_seq_cst。例如:

f.clear(std::memory_order_release); // 1

bool x = f.test_and_set();  // 2

这里,调用clear()①明确要求,使用释放语义清除标志,当调用test_and_set()②使用默认内存顺序设置表示,并且检索旧值。

你不能拷贝构造另一个std::atomic_flag对象;你也不能将一个对象赋予另一个std::atomic_flag 对象。这并不是 std::atomic_flag 特有的,而是所有原子类型共有的。 一个原子类型的所有操作都是原子的,因赋值和拷贝调用了两个对象,这就就破坏了操作的原子性。在这样的情况下,拷贝构造和拷贝赋值都会将第一个对象的值进行读取,然后再写入另外一个。对于两个独立的对象,这里就有两个独立的操作了,合并这两个操作必定不是原子的。因此,操作就不被允许。

有限的特性集使得 std::atomic_flag 非常适合于作自旋互斥锁。初始化标志是“清除”,并且互斥量处于解锁状态。为了锁上互斥量,循环运行test_and_set()直到旧值为false,就意味着这个线程已经被设置为true了。解锁互斥量是一件很简单的事情,将标志清除即可。实现如下面的程序清单所示:

清单5.1 使用 std::atomic_flag 实现自旋互斥锁

class spinlock_mutex
{std::atomic_flag flag;public:spinlock_mutex() : flag(ATOMIC_FLAG_INIT){}void lock(){while(flag.test_and_set(std::memory_order_acquire));}void unlock(){flag.clear(std::memory_order_release);}
};

这样的互斥量是最最基本的,但是它已经足够 std::lock_guard<> 使用了(详见第3章)。其本质就是在lock()中等待,所以这里几乎不可能有竞争的存在,并且可以确保互斥。当我们看到内存顺序语义时,你将会看到它们是如何对一个互斥锁保证必要的强制顺序的。这个例子将在 5.3.6节中展示。

由于 std::atomic_flag 局限性太强,因为它没有非修改查询操作(注:c++20以后才新增test()函数,对atomic_flag状态无修改的只读访问函数),它甚至不能像普通的布尔标志那样使用。所以,你最好使用std::atomic<bool> ,接下来让我们看看应该如何使用它。

5.2.2 std::atomic_flag的相关操作相关推荐

  1. 5.2.3 std::atomic的相关操作

    5.2.3 std::atomic的相关操作 最基本的原子整型类型就是 std::atomic<bool> .如你所料,它有着比 std::atomic_flag更加齐全的布尔标志特性.虽 ...

  2. 多项式相关操作学习笔记

    多项式相关操作学习笔记 标签: 多项式 说在前边 记录一下相关的多项式操作,顺便存个模板.(多点求值之后的部分,有点写不动了...留坑留坑 多项式 定义 给定一个环\(R\)(\(R\)通常是交换环, ...

  3. 双向链表的创建和相关操作

    http://blog.csdn.net/jw903/article/details/38947753 双向链表其实是单链表的改进. 当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时, ...

  4. (C++版)链表(一)——实现单向链表创建、插入、删除等相关操作

    http://blog.csdn.net/fisherwan/article/details/25557545 前段时间用C语言实现了链表的相关操作,但是发现当时挺清楚的,过了一段时间又忘的差不多了, ...

  5. 5.2.5 标准的原子整型的相关操作

    5.2.5 标准的原子整型的相关操作 如同普通的操作集合一样(load(), store(), exchange(), compare_exchange_weak(), 和 compare_excha ...

  6. C++文件流fstream相关操作

    C++文件流fstream相关操作 一.理解Open函数 利用fstream,使用open/close打开或创建,完成后关闭,对文件读入读出使用插入器(<<) 或析取器(>>) ...

  7. String转QString,线段相交,四点共面,git相关操作,截图,扩展工具,string乱码,矩阵相乘

    20220513-20220608.QT String转QString 两线段是否相交 四个点是否共面,两个直线是否相交 git相关操作 截图快捷键 shift+win+s VS2013扩展工具不能联 ...

  8. 基于Ubuntu安装opencv以及相关操作

    目录 一.基于Ubuntu下安装opencv 二.相关操作之图片 三.相关操作之视屏 四.总结 五.参考资料 一.基于Ubuntu下安装opencv 1.opencv依赖环境的安装 1.1 安装cma ...

  9. 【Linux】一篇文章搞定 进程 及相关操作

    文章目录 Linux下进程相关操作1. 进程概念1.1 进程基本概念1.2 Linux下PCB的定义2.进程查看3. 进程创建3.1 fork函数3.2 vfork函数3.3 fork与vfork的异 ...

最新文章

  1. javascript重置(base层)(。。。。不完整)
  2. 【RocketMQ工作原理】
  3. ubuntu12.0.4不能正常关机和重启的解决方法
  4. 怎么学python-初学者如何学习Python?掌握这17个实用小技巧快速入门!
  5. Linux学习之内核模块编程
  6. Sqlmap查找SQL注入漏洞入门
  7. 你觉得一个128g主力机用几年会到非换不可的程度?
  8. win7 linux启动设置u盘启动,在linux下怎么样制作win7的U盘启动?
  9. CodeForces 274B Zero Tree :每次选包含1节点的一棵子树,将该子树所有值都+1或者-1最少多少步可以使树值全部为0 :树型dp...
  10. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题HIL
  11. if __name__ == __main__如何正确理解
  12. 编译原理 第3版 第一章练习
  13. C语言的考试系统,C语言考试系统.doc
  14. 德州大学计算机系郭小虎2021,2021美国德州农工大学PhD项目
  15. 缺陷跟踪系统BugTracker。 以下对使用
  16. 如何做顶级“新生代农民工”?这几本书为你打开大门
  17. 机器人程序设计入门(C++/Arduino/ROS)(转载2020版)
  18. Carsim与Simulink联仿Carsim找不到Matlab错误的解决方案,此前装过多个Matlab版本出现该问题可以尝试此方法
  19. 文件上传(图片上传) 大小限制的配置 及注意点
  20. 基于IDL的高分二号影像批量预处理程序

热门文章

  1. 零起点英语_【德国零起点】05—变元音字母
  2. java 字符串连接_为什么 Java 要把字符串设计成不可变的
  3. Spring框架错误之org.springframework.beans.factory.BeanCreationException
  4. php 并发控制中的独占锁
  5. java查询mongodb 嵌套,查询嵌套文件mongoDB
  6. php单独使用blade模板引擎,laravel 基础教程 —— Blade 模板引擎
  7. 解决Exchange用户邮箱别名为乱码的问题
  8. c++ const
  9. ORACLE 数据同步时,批量进行新增和更新操作的SQL写法
  10. php图片合并png保存图片大小,php缩放处理png和jpg图片