本文主要是介绍std::atomic类模板的学习(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.引言
std::atomic是一个c++的模板类,为了解决线程访问共享资源时出现数据竞争问题。atomic的翻译成中文的意思是原子的,这里指的就是原子操作的意思。什么是原子操作呢?看到一个代码示例讲的挺好的。
int value = 0;
void atomic_function() {for (int i = 0; i < 100; ++i)value += 1;
}
我们在线程A里面调用以上atomic_function函数时,我们在线程B里观察value的结果。如果是原子操作,那么观察的value值要么是0,要么是100;如果是非原子操作,value的值被观测时,可能是0~100的任何一个整数值。示例中函数不加特殊处理,肯定不是原子操作,只是拿来理解原子操作的概念。
2. 基本信息
头文件
#include< <atomic>
类型定义
template< class T >
struct atomic;
3.对于整数类型的示例化
std::atomic模板类可对以下整数类型进行实例化
字符类型:
char
char8_t (C++20)
char16_t
char32_t
wchar_t
标准有符号整数类型:
signed char
short
int
long
long long
标准无符号整数类型:
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
std::atomic模板类对以上整数类型的实例化对象提供原子操作,例如
fetch_add
fetch_sub
fetch_and
fetch_or
fetch_xor
4 std::atomic<int>的原子操作fetch_add使用demo
fetch_add的函数原型
T fetch_add
(T arg, std::memory_order order = std::memory_order_seq_cst
);
参数
arg - 算术加法的另一参数
order - 强制的内存顺序制约,默认情况下为std::memory_order_seq_cst 。
内存顺序制约比较难理解,初学暂且放下。接下来看fetch_add的使用案例。文件名:atomic.c
#include<iostream>
#include<thread>
#include<atomic>std::atomic<int> atomic_data;void AtomicAdd(void)
{for(int i = 0; i < 1000000; i++){atomic_data.fetch_add(1);}
}int main(int argn, char* argv[])
{std::cout << "hello atomic fetch_add" << std::endl;std::thread th1(AtomicAdd);std::thread th2(AtomicAdd);std::thread th3(AtomicAdd);th1.join();th2.join();th3.join();std::cout << "atomic_data Val:" << atomic_data << std::endl;return 0;
}
同目录下写一个简单的Makefile,省的每次都写g++编译语句,如下:
TGT := main
SRC := atomic.c
OPTION := -I.
OPTION += -pthreadall: $(TGT)@echo "make sucessfull"$(TGT):$(SRC)g++ -std=c++11 $^ $(OPTION) -o $@clean:rm $(TGT)
.PHONY: all clean
编译后,运行结果如下:
hello atomic fetch_add
atomic_data Val:3000000
这篇关于std::atomic类模板的学习(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!