C++98
标准中并没有线程库的存在。C++11
中才提供了多线程的标准库,提供了thread
、mutex
、condition_variable
、atomic
等相关对象及功能功能。
1. atomic
std::atomic<>
是一个模板类,使用该模板类实例化的对象,提供了一些保证原子性的成员函数来实现共享数据的常用操作。其原型如下:
template <class T>
struct atomic;
- 简单来说,
std::atomic<>
就是用来定义一个自动加锁解锁的共享变量(“定义”“变量”用词在这里是不准确的,但是更加贴切它的实际功能),供多个线程访问而不发生冲突。
1.1 构造函数
- atomic的构造函数如下所示:
atomic() noexcept = default; // 1. default,调用atomic_init 进行初始化
constexpr atomic(T val) noexcept; // 2. initialization
atomic(const atomic&) = delete; // 3. copy [deleted]
- 测试代码:
std::atomic<int> num_1; // 1. 默认初始化,全局变量为 0初始化
std::atomic<int> num_2(999); // 2. 赋值
int main(){
std::atomic<int> num_loc; // 3. 默认初始化, 局部变量为 int 随机值
std::cout << "num_loc: " << num_loc << std::endl;
std::cout << "num_1: " << num_1 << std::endl;
std::cout << "num_2: " << num_2 << std::endl;
return 0;
}
num_loc: 4197984
num_1: 0
num_2: 999
1.2 成员函数
-
atomic
成员函数如下所示:
-
值得一提的是,上图中
func-specializations
为具体化类型可以使用的成员函数。具体化类型如下图所示:
-
普通成员函数中,
store
是原子写操作,load
是原子读操作。exchange
是于两个数值进行交换的原子操作
void store(T val, memory_order sync = memory_order_seq_cst) volatile noexcept; // 1. store
void store(T val, memory_order sync = memory_order_seq_cst) noexcept;
T load(memory_order sync = memory_order_seq_cst) const volatile noexcept; // 2. load
T load(memory_order sync = memory_order_seq_cst) const noexcept;
T exchange(T val, memory_order sync = memory_order_seq_cst) volatile noexcept; // 3. exchange
T exchange(T val, memory_order sync = memory_order_seq_cst) noexcept;
- 对于上述操作,需要考虑内存顺序
memory_order
。详情见 www.cplusplus.com
std::atomic<int64_t> value(10);
int64_t num = 10;
int64_t x = value.load(std::memory_order_relaxed); // 读取变量值(原子对象)
x.store(num,std::memory_order_relaxed) // 更新变量(原子对象)