一、原子变量
- 原子操作:原子操作是不可分割的操作,要么完全执行,要么完全不执行。在多线程环境中,原子操作可以确保数据的一致性。需要头文件。
1、初始化
std::atomic 支持多种数据类型,包括:
- 基本类型:
int、long、bool等。 - 指针类型:
T*。 - 用户自定义类型(需要满足一定的条件)。
示例:定义 atomic 变量
#include <atomic>
using namespace std;
atomic<int> counter(0); // 原子整型变量
atomic<bool> flag(false); // 原子布尔变量
std::atomic 提供了多种原子操作,包括:
2、操作
- 加载(Load) :读取原子变量的值。
- 存储(Store) :写入原子变量的值。
- 交换(Exchange) :将原子变量的值替换为新值,并返回旧值。
- 比较交换(Compare-and-Swap, CAS) :如果原子变量的值等于预期值,则将其替换为新值。
- 加减操作:对原子变量进行加减操作。
3、顺序
-
std::atomic:封装了一个值,并提供了对该值的原子操作。std::atomic支持多种内存顺序(Memory Order),用于控制原子操作的内存可见性。常见的内存顺序包括: -
memory_order_relaxed:只保证原子性,不保证顺序。 -
memory_order_acquire:保证后续操作不会重排序到当前操作之前。 -
memory_order_release:保证前面的操作不会重排序到当前操作之后。 -
memory_order_seq_cst:最严格的内存顺序,保证所有操作的顺序一致性。
#include <iostream>
#include <atomic>
#include <thread>
using namespace std;
atomic<int> data(0);
atomic<bool> ready(false);
void producer() {
data.store(42, memory_order_relaxed); // 存储数据
ready.store(true, memory_order_release); // 发布数据
}
void consumer() {
while (!ready.load(memory_order_acquire)); // 等待数据准备好
cout << "Data: " << data.load(memory_order_relaxed) << endl; // 读取数据
}
int main() {
thread t1(producer);
thread t2(consumer);
t1.join();
t2.join();
return 0;
}