c++ 11 原子操作库 (std::atomic)(三)
定义于头文件 <atomic>
atomic 类模板及其针对布尔、整型和指针类型的特化
每个 std::atomic
模板的实例化和全特化定义一个原子类型。若一个线程写入原子对象,同时另一线程从它读取,则行为良好定义(数据竞争的细节见内存模型)。
另外,对原子对象的访问可以建立线程间同步,并按 std::memory_order 所对非原子内存访问定序。
std::atomic
既不可复制亦不可移动。
令原子值增加或减少一
std::atomic<T>::operator++,++(int),--,--(int)
T operator++() noexcept; |
(1) |
(仅为 atomic<Integral> 模板特化的成员)(C++11 起) |
T* operator++() noexcept; |
(1) |
(仅为 atomic<T*> 模板特化的成员)(C++11 起) |
T operator++( int ) noexcept; |
(2) |
(仅为 atomic<Integral> 模板特化的成员)(C++11 起) |
T* operator++( int ) noexcept; |
(2) |
(仅为 atomic<T*> 模板特化的成员)(C++11 起) |
T operator--() noexcept; |
(3) |
(仅为 atomic<Integral> 模板特化的成员)(C++11 起) |
T* operator--() noexcept; |
(3) |
(仅为 atomic<T*> 模板特化的成员)(C++11 起) |
T operator--( int ) noexcept; |
(4) |
(仅为 atomic<Integral> 模板特化的成员)(C++11 起) |
T* operator--( int ) noexcept; |
(4) |
(仅为 atomic<T*> 模板特化的成员)(C++11 起) |
原子地自增或自减当前值。操作为读-修改-写操作。
1) 进行原子前自增。等价于 fetch_add(1)+1 。
2) 进行原子后自增。等价于 fetch_add(1) 。
3) 进行原子前自减。等价于 fetch_sub(1)-1 。
4) 进行原子后自减。等价于 fetch_sub(1) 。
对于有符号整数 (Integral
) 类型,算术定义为使用补码表示。无未定义结果。对于 T*
类型,结果可能为未定义地址,但这些操作不会另有未定义行为。
参数
(无)
返回值
1,3) 修改后的原子变量的值。正式地说, *this
的修改顺序中自增/自减值的结果立即前趋于此函数的效果。
2,4) 修改前的原子变量的值。正式地说, *this
的修改顺序中值立即前趋于此函数的效果。
注意
不同于大多数前自增和自减运算符,原子类型的前自增和自减运算符不返回被修改对象的引用。它们替而返回存储值的副本。
加、减,或与原子值进行逐位与、或、异或
std::atomic<T>::operator+=,-=,&=,|=,^=
仅为 atomic<Integral>(C++11) 与 atomic<Floating>(C++20) 模板特化的成员
T operator+=( T arg ) noexcept; |
||
T operator+=( T arg ) volatile noexcept; |
仅为 atomic<T*> 模板特化的成员
T* operator+=( std::ptrdiff_t arg ) noexcept; |
||
T* operator+=( std::ptrdiff_t arg ) volatile noexcept; |
仅为 atomic<Integral>(C++11) 与 atomic<Floating>(C++20) 模板特化的成员
T operator-=( T arg ) noexcept; |
||
T operator-=( T arg ) volatile noexcept; |
仅为 atomic<T*> 模板特化的成员
T* operator-=( std::ptrdiff_t arg ) noexcept; |
||
T* operator-=( std::ptrdiff_t arg ) volatile noexcept; |
仅为 atomic<Integral> 模板特化的成员
T operator&=( T arg ) noexcept; |
||
T operator&=( T arg ) volatile noexcept; |
||
T operator|=( T arg ) noexcept; |
||
T operator|=( T arg ) volatile noexcept; |
||
T operator^=( T arg ) noexcept; |
||
T operator^=( T arg ) volatile noexcept; |
原子地以涉及先前值和 arg
的计算结果替换当前值。操作是读-修改-写操作。
1) 进行原子加法。等价于 fetch_add(arg) + arg 。
2) 进行原子减法。等价于 fetch_sub(arg) - arg 。
3) 进行原子逐位与。等价于 fetch_and(arg) & arg 。
4) 进行原子逐位或。等价于 fetch_or(arg) | arg 。
5) 进行原子逐位异或。等价于 fetch_xor(arg) ^ arg 。
对于有符号整数 (Integral
) 类型,算术定义为使用补码表示。无未定义结果。
对于浮点类型,有影响的浮点环境可能异于调用方线程的浮点环境。操作不必服从对应的 std::numeric_limits 特性,但鼓励这么做。若结果不是其类型所能表示的值,则结果未指定,但操作不会另有未定义行为。 |
(C++20 起) |
对于 T*
类型,结果可能为未定义地址,但操作不会另有未定义行为。若 T
不是对象类型则程序为病式。
参数
arg | - | 算术运算的参数 |
返回值
返回值(即应用对应二元运算符到 *this
的修改顺序中立即前趋于成员对应函数效果的值)
注意
不同于大多数复合赋值运算符,原子类型的复合赋值运算符不返回到其左侧运算数的引用。它们替而返回存储的值的副本。
原子地将参数加到存储于原子对象的值,并返回先前保有的值
std::atomic<T>::fetch_add
仅为 atomic<Integral>(C++11) 与 atomic<Floating>(C++20) 模板特化的成员
T fetch_add( T arg, |
||
T fetch_add( T arg, |
仅为 atomic<T*> 模板特化的成员
T* fetch_add( std::ptrdiff_t arg, |
||
T* fetch_add( std::ptrdiff_t arg, |
原子地以值和 arg
的算术加法结果替换当前值。运算是读修改写操作。按照 order
的值影响内存。
对于有符号 Integral
类型,定义算术为使用补码。无未定义结果。
对于浮点类型,有影响的浮点环境可能异于调用方线程的浮点环境。操作不必服从对应的 std::numeric_limits 特性,但鼓励这么做。若结果不是其类型所能表示的值,则结果未指定,但其他情况下操作无未定义行为。 |
(C++20 起) |
对于 T*
类型,结果可能为未定义的地址,但其他情况下运算无未定义行为。
参数
arg | - | 算术加法的另一参数 |
order | - | 强制的内存顺序制约 |
返回值
*this
的修改顺序中,立即前趋此函数效应的值。
调用示例
#include <iostream>
#include <thread>
#include <atomic>std::atomic<long long> data;
void do_work()
{data.fetch_add(1, std::memory_order_relaxed);
}int main()
{std::thread th1(do_work);std::thread th2(do_work);std::thread th3(do_work);std::thread th4(do_work);std::thread th5(do_work);th1.join();th2.join();th3.join();th4.join();th5.join();std::cout << "Result:" << data << '\n';
}
原子地从存储于原子对象的值减去参数,并获得先前保有的值
std::atomic<T>::fetch_sub
仅为 |
||||
T fetch_sub( T arg, |
(1) | (2) | ||
T fetch_sub( T arg, |
||||
仅为 |
||||
T* fetch_sub( std::ptrdiff_t arg, |
||||
T* fetch_sub( std::ptrdiff_t arg, |
以值和 arg
的算术减法结果原子地替换当前值。操作是读修改写操作。按照 order
的值影响内存。
对于有符号 Integral
类型,定义算术为使用补码表示。无未定义结果。
对于浮点类型,有影响的浮点环境可能异于调用方线程的浮点环境。操作不必服从对应的 std::numeric_limits 特性,但鼓励这么做。若结果不是其类型所能表示的值,则结果未指定,但操作不会另有未定义行为。 |
(C++20 起) |
对于 T*
类型,结果可能是未定义地址,但操作不会另有未定义行为。若 T
不是对象类型则程序为病式。
参数
arg | - | 算术减法的另一参数 |
order | - | 强制的内存顺序制约 |
返回值
*this
的修改顺序中立即前趋此函数效果的值。
原子地进行参数和原子对象的值的逐位与,并获得先前保有的值
std::atomic<T>::fetch_and
T fetch_and( T arg, |
||
T fetch_and( T arg, |
原子地以值和 arg
逐位与的结果替换当前值。运算是读修改写操作。按照 order
的值影响内存。
参数
arg | - | 逐位与的另一参数 |
order | - | 强制的内存顺序制约 |
返回值
*this
的修改顺序中立即前趋此函数效果的值。
原子地进行参数和原子对象的值的逐位或,并获得先前保有的值
std::atomic<T>::fetch_or
T fetch_or( T arg, |
||
T fetch_or( T arg, |
原子地以值和 arg
逐位或的结果替换当前值。运算为读修改写操作。按照 order
的值影响内存。
参数
arg | - | 逐位或的另一参数 |
order | - | 强制的内存顺序制约 |
返回值
*this
的修改顺序中立即前趋此函数效果的值。
原子地进行参数和原子对象的值的逐位异或,并获得先前保有的值
std::atomic<T>::fetch_xor
T fetch_xor( T arg, |
||
T fetch_xor( T arg, |
原子地以值和 arg
逐位异或的结果替换当前值。运算是读修改写操作。按照 order
的值影响内存。
参数
arg | - | 逐位异或的另一参数 |
order | - | 强制的内存顺序制约 |
返回值
*this
的修改顺序中立即前趋此函数效果的值。
c++ 11 原子操作库 (std::atomic)(三)相关推荐
- 走进C++11(三十七)原子操作之 std::atomic
关注公众号获取更多信息: C++11提供了一个原子类型std::atomic<T>,可以使用任意类型作为模板参数,C++11内置了整型的原子变量,可以方便的使用原子变量,使用原子变量就不用 ...
- c++ 11 原子操作库 (std::atomic)(一)
定义于头文件 <atomic> atomic 类模板及其针对布尔.整型和指针类型的特化 template< class T > struct atomic; (1) (C ...
- c++ 11 原子操作库 (std::atomic)(二)
定义于头文件 <atomic> atomic 类模板及其针对布尔.整型和指针类型的特化 每个 std::atomic 模板的实例化和全特化定义一个原子类型.若一个线程写入原子对象,同时另一 ...
- C++11 并发指南六( atomic 类型详解二 std::atomic )
C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍) 一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...
- C++11中头文件atomic的使用
原子库为细粒度的原子操作提供组件,允许无锁并发编程.涉及同一对象的每个原子操作,相对于任何其他原子操作是不可分的.原子对象不具有数据竞争(data race).原子类型对象的主要特点就是从不同线程访问 ...
- C++11 多线程(std::thread)详解
注:此教程以 Visual Studio 2019 Version 16.10.3 (MSVC 19.29.30038.1) 为标准,大多数内容参照cplusplus.com里的解释 此文章允许转载, ...
- C++11并发之std::thread
C++11并发之std::thread 知识链接: C++11 并发之std::mutex C++11 并发之std::atomic 本文概要: 1.成员类型和成员函数. 2.std::thread ...
- Item 40: Use std::atomic for concurrency, volatile for special memory.
Item 40: Use std::atomic for concurrency, volatile for special memory. 本 Item 探讨一下 atomic 类型和 volati ...
- C++11 并发指南六(atomic 类型详解三 std::atomic (续))
C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...
- std::atomic原子操作
1.原子操作介绍 在多线程编程中,经常使用互斥锁锁住一段代码块,实现线程同步.原子操作可以看成是对变量的互斥锁.比如程序中一个线程读取一个变量,另一个线程修改该变量的值,那么采用原子操作可以不用添加互 ...
最新文章
- groovy怎样从sql语句中截取表名_SQL常用的基础查询语句
- 谈谈对 Canal( 增量数据订阅与消费 )的理解--大数据平台技术栈系列(3)
- 在Linux的Eclipse下搭建Android环境
- 走在专家的路上,每天一条SQL优化(3)
- [BZOJ1131][POI2008]Sta
- 【教程】Linux 系统下对目录扩容的方法
- Windows 8的无线设置后,竟不能直接更改,目前知道可以通过命令行解决
- 在做TLS/SSL时报错
- C语言实现随机生成0~100的数
- Segment,Path,Ring和Polyline对象
- 容斥 - HDU 4135 Co-prime
- httpservletrequest 设置请求头_大部分程序员不知道的 Servelt3 异步请求,原来这么简单?
- LVS负载均衡的几种模式和算法
- 17.Mac Ctags 使用
- 【java毕业设计】基于javaEE+SSM+MySql的BS架构微博系统设计与实现(毕业论文+程序源码)——BS架构微博系统
- 【戴明环】PDCA-问题闭环思维模型
- Typora+picgo+gitee图片外链失效,Typora历史笔记无法显示图片
- 明尼苏达大学计算机工程,关于美国明尼苏达大学电气与计算机工程系洪明毅博后学术报告的通知...
- 重读《从菜鸟到测试架构师》-- 测试专家的第一步
- 判断无向图G是否是一颗树