xample标准库stdatomic及stdmemoryorder腾讯云开发者社区

原子操作是多线程当中对资源进行保护的一种手段,主要作用是和互斥量(Mutex)一样,避免对资源的并发访问、修改。

互斥量的粒度衡量是作用域(哪怕作用域内只有一个变量),而原子的粒度衡量则是以一个变量或对象为单位。因此,原子相对于互斥量更加高效,但并非替代关系。

互斥量的主要作用是保护作用域内的资源,而原子的作用是保护一个变量或对象。

因此,当你需要保护的资源仅仅是某个变量或对象时,应首先考虑使用原子。

如果你并不明白 std::atomic (原子) 的作用,请看以下代码及执行结果:

执行结果:

以上代码分别定义了两个 int 变量,一个是普通的变量,一个是原子变量。两个变量分别用两个线程去递增1000000次。

理论上,两个变量最终值应同为2000000。然而,普通变量却出现了资源竞争性错误,两个线程都有接近一半的操作都是失败的,导致最终值仅为1123299。

而受原子保护的变量,两个线程的操作则全部成功。

名称

作用

适用内存序

operator=

重载等

operator T

从原子对象加载值

store

memory_order_relaxedmemory_order_releasememory_order_seq_cst

load

从原子对象当中加载值(返回)

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_seq_cst

is_lock_free

检查原子对象的锁定状态

wait 【std20】

阻塞线程至被提醒且原子值更改

exchange

用另一个原子值替换当前原子值 并返回先前的原子值

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

compare_exchange_weak

原子地比较原子对象与非原子参数的值,若相等则进行交换,若不相等则进行加载(允许少部分不符合条件的值返回)

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

compare_exchange_strong

原子地比较原子对象与非原子参数的值,若相等则进行交换,若不相等则进行加载

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

notify_one【std20】

通知至少一个在该原子对象等待线程

notify_all【std20】

通知所有在该原子对象等待线程

[常量] is_always_lock_free

指示该类型是否始终免锁

除此之外 std::atomic 还对 int 及指针类型做了特殊化增强,以下操作函数仅适用于 int 及指针类型操作:

额外备注:C++ 20 后部分特化支持 float 。

名称

作用

适用特化类型

适用内存序

fetch_add

原子地将参数加到存储于原子对象的值,并返回先前保有的值

int && ptr && float(std20)

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

fetch_sub

原子地从存储于原子对象的值减去参数,并获得先前保有的值

int && ptr && float(std20)

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

fetch_and

原子地进行参数和原子对象的值的逐位与,并获得先前保有的值

int

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

fetch_or

原子地进行参数和原子对象的值的逐位或,并获得先前保有的值

int

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

fetch_xor

原子地进行参数和原子对象的值的逐位异或,并获得先前保有的值

int

memory_order_relaxedmemory_order_consumememory_order_acquirememory_order_releasememory_order_acq_relmemory_order_seq_cst

operator++

原子值递增

int && ptr

operator--

原子值递减

int && ptr

operator+=

原子值增加

int && ptr && float(std20)

operator-=

原子值减少

int && ptr && float(std20)

operator&=

进行原子按位与

int

operator|=

进行原子按位或

int

operator^=

进行原子按位异或

int

std::atomic_flag 是原子的最基本布尔类型,它是无锁的,并且它没有拷贝构造函数,也不提供 load 和 store 操作。主要用于提供比 std::atomic 更简单基本化布尔操作效率。

构造语法:

成员函数表:

名称

作用

operator=

重载等

clear

将布尔值设置为 false

test_and_set

将布尔值设置为 true 并返回先前值

test【std20】

原子的返回当前值

wait

阻塞线程至被提醒且原子值更改

notify_one【std20】

通知至少一个在该原子对象等待线程

notify_all【std20】

通知所有在该原子对象等待线程

std::memory_order 指定内存访问,包括常规的非原子内存访问,如何围绕原子操作排序。在没有任何制约的多处理器系统上,多个线程同时读或写数个变量时,一个线程能观测到变量值更改的顺序不同于另一个线程写它们的顺序。其实,更改的顺序甚至能在多个读取线程间相异。一些类似的效果还能在单处理器系统上出现,因为内存模型允许编译器变换。库中所有原子操作的默认行为提供序列一致顺序(见后述讨论)。该默认行为可能有损性能,不过可以给予库的原子操作额外的 std::memory_order 参数,以指定附加制约,在原子性外,编译器和处理器还必须强制该操作。-- 《C++ Reference》

要理解内存序是做什么的,要先从硬件讲起:(尽量简单通俗)

以一颗 CPU i7-10875H 为例,它有8颗物理内核,从物理上来讲,它可以同时处理8条并行线程,通过超线程技术可以扩展到16条线程(物理上还是8条)。

再在软件层面来讲,并行的数千条线程是逻辑并行,终究都要交给 CPU 进行串行处理,而 CPU 可以同时处理的线程数量,就是由内核数量决定的。

而每个 CPU 内核所运算数据的存取,并不是直接存取到内存当中,而是要先经过每个内核互相独立的 L1、L2 两级高速缓存,再到 CPU 内核之间共享的 L3 高速缓存,再然后到内存。

这样就造成了一个问题,就是,假设一个内核负责的一条线程修改了某个变量的值,但是还没有刷新到内核之间共享的 L3 缓存或者内存之中,那么这时候其他 CPU 内核从内存中读取到的该变量就仍然是旧值。

所以,为了避免这种情况,这就是 std::memory_order 的作用。

首先,要明白 std::memory_order 本身是什么,它是定义于 <atomic> 头文件当中的六个枚举值,使用时用做参数传递给 std::atomic 相关的操作函数,比如 load、store 等。

名称

作用

memory_order_relexed

只保证原子值不被其他线程同时访问,但没有线程之间同步、顺序制约,其他线程可能读取到内存当中的旧值。

memory_order_consume

memory_order_acquire

memory_order_release

有顺序的释放操作,作用是保证之后的 load(读)、store(写) 性质操作不会排在传入该枚举值的操作函数之前。

memory_order_acq_rel

有顺序整合加载(memory_order_acquire)->释放(memory_order_release)操作。当前线程的所有 load(读)、store(写) 性质操作不会排在传入该枚举值的操作函数之前后。所有带有释放(memory_order_release)操作同一原子对象的线程会排在传入该枚举值的操作函数之前。而且当前线程对原子值的修改会同步给其他进行读操作的同一原子对象的线程。

memory_order_seq_cst

传入该枚举值的操作函数,load(读) 时会进行 memory_order_acquire 操作,store(写)时会进行 memory_order_release 操作。如果是读+写就是 memory_order_acq_rel 操作。备注:此枚举值为支持传入 std::memory_order 操作函数的缺省值。

THE END
0.[Java基础]有参构造方法和无参构造方法本文详细介绍了Java中的构造方法,包括无参构造方法和有参构造方法的概念与使用方式,并通过具体示例阐述了如何正确使用这两种构造方法。 java构造方法:有参构造方法和无参构造方法 一、无参构造方法 1、定义: 如果编写一个javaBean时没有添加无参构造方法,那么编译器会自动添加无参构造方法; jvzquC41dnuh0lxfp0tfv8mkij813:4ctvodnn4fgvgjn|4729>96A=
1.装饰装修材料与构造(十一)第十四章  墙面与柱面装饰装修构造图 墙面是室内空间中的垂直界面,墙面的装饰装修是室内设计中非常重要的内容。墙面装饰装修除对室内起美化作用外,还有保护墙体、保证室内使用等功能,如防潮、防污、防撞击和声光反射、吸声、保温、隔热等。 墙面装饰装修的基本构造包括底层、中间层、饰面层三部分。 jvzq<84l|{y/e}{0ukv0niw0et04973138268h63c::6<71rcmf0qyo
2.计算机程序的构造和解释(原书第2版)(豆瓣)《计算机程序的构造和解释》成型于美国麻省理工学院(MIT)多年使用的一本教材,1984年出版,1996年修订为第二版。在过去的二十多年里,该书对于计算机科学的教育计划产生了深刻的影响。 在第二版中,大部分重要程序设计系统都重新修改并做过测试,包括各种解释器和编译器。作者根据其后十余年的教学实践,还对其他许多细节jvzquC41dqul0mtwdct/exr1uwhkgly133:94A71
3.宇宙的构造(豆瓣)一部由 PBS 出品、极富视觉冲击力的科普巨作,一场用画面演绎和探寻宇宙终极奥秘的讲堂。从牛顿因苹果产生的力学顿悟,到爱因斯坦相对论,再到量子论,弦理论……《宇宙的构造》共四部分,取材自同名著作,作者兼物理学家 Brian Greene 和世界名校的专家学者一同为观众介绍时间、空间和宇宙的概念。 jvzquC41oq|jg7iqwdgo0lto1u{clnhv14:9;:9;8
4.[风华国乐]国乐微课堂·笙的构造正在播放[风华国乐]国乐微课堂·笙的构造 《风华国乐》 20240315 00:29:24 本期内容 [风华国乐]《春风十万里》 演奏:唐俊乔 孙艺祯 00:02:34 [风华国乐]《好春光》 演奏:云尚音乐 00:02:41 [风华国乐]《水乡小唱》 演奏:浙江歌舞剧院·彩蝶女乐 00:04:21 [风华国乐]《欢庆》 演奏:姜淼 赵勃楠 00:jvzquC41vx4de}{0eqs0497612903>4XKFK89QXIYk|7r~sN281ExF4629277xjvor
5.构造地质学研究生党团支部开展“请党放心,强国有我”系列党团日活动为充分发挥党团支部的先锋模范与带头引领作用和激发党团员更加坚定自觉地为党的事业贡献青春智慧和时代力量,近期,构造地质学研究生党支部同构造地质学博士生团支部、构造地质学硕士生团支部、2021级本科生2班团支部联合开展了“请党放心,强国有我”主题系列党团日活动。活动以党建带团建,构造地质学研究生党支部三个党jvzquC41ugyt0ypw0gjv0ls1kplp1:7451959B3jvo
6.中国石油大学(北京)克拉玛依校区石油学院2017年11月到中国石油大学(北京)克拉玛依校区任教。担任构造地质课程群负责人。主要开展构造地质学专业教学工作及前陆盆地构造模拟实验室建设工作。 工作期间主持或参加国家、中石油股份公司及自治区项目13项,承担中石油、中石化科技攻关项目4项,获得省部级奖励9项,局级奖励2项,发表论文40篇,其中第一作者(通讯作者)论文jvzquC41yy}/e~um0gjv0ls1u{~z1l4423=.3:24:1::3@870unuou
7.玉髓是什么玉髓价格玉髓和玉的区别玉石图鉴金投珠宝玉髓是隐晶质集合体,内部分子微小,肉眼观察不到,所以十分细腻,它以乳房状或钟乳状产出,常呈肾状、鈡乳状、葡萄状等。玛瑙是经常混有蛋白石和隐晶质石英的纹带状块体,常见的为同心圆构造,颜色不一,视其所含杂质种类及多寡而定,通常呈条带状、同心环状、云雾状或树枝状分布。 jvzquC41|j{ccx3epiumf7tti1tvs4e47?49A90jvsm
8.湖南科技大学资源环境与安全工程学院2003年6月毕业于长安大学构造地质学专业,获理学硕士学位。2006年6月毕业于于中科院广州地球化学研究所构造地质学专业,获理学博士学位。2006年起在湖南科技大学地质系任教,同年评为讲师,2008年任副教授,2013年晋升为教授。2009年被评为硕士生导师。主要从事构造地质学、大地构造与成矿及地质灾害等方面的研究,近年来jvzquC41|c~z0qswuv4ff~3ep1y{f€4f|iiy1sxf|1k2:kghf8<3eA97d7?g9j=9g3?13jj4584ivv