C++-atomic类型介绍

本文通过示例展示了在多线程环境下,非原子操作可能导致的竞争条件,而使用std::atomic可以避免这种情况,确保数据在并发访问时的正确性。在示例中,对比了非原子变量n和原子变量atomic_n在多线程加法操作后的结果,结果显示非原子变量的结果不正确,而原子变量保持了预期的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

atomic

std::atomic是一个模板类,模板参数为数据类型。atomic对象的一个重要特性就是多线程同时读写该变量时不会产生竞争条件,任意时刻只有一个线程对这个资源进行访问。

#include <thread>
#include <vector>
#include <iostream>

using namespace std;

int n;
atomic<int> atomic_n;

void adder1()
{
	for (int i = 0; i < 10000; i++)
	{
		n++;
	}
}

void adder2()
{
	for (int i = 0; i < 10000; i++)
	{
		atomic_n++;
	}
}

int main()
{
	n = atomic_n = 0;
	vector<thread*> threadVec;
	for (int i = 0; i < 100; i++)
	{
		thread* t = new thread(adder1);
		threadVec.push_back(t);
	}
	for (int i = 0; i < 100; i++)
	{
		thread* t = new thread(adder2);
		threadVec.push_back(t);
	}
	for (auto iter = threadVec.begin(); iter != threadVec.end(); iter++)
	{
		(*iter)->join();
	}
	cout << n<<endl;
	cout << atomic_n<<endl;
}

输出:

711123
1000000

可以看到如果不是atomic类型且没有加锁的情况下,多个线程同时读写同一个变量会出现竞争条件,导致最终值不等于1000000

C语言中的`<stdatomic.h>`库提供了原子操作接口,用于实现线程安全的原子操作。原子操作是不可被中断的,即在执行原子操作期间不会有其他线程干扰。 在C11标准中,`<stdatomic.h>`库引入了一组原子类型和原子操作函数。这些原子类型和函数可以用于实现共享变量的原子访问、更新和同步。 下面是一些常用的原子类型和相关函数: 1. `atomic_flag`类型:用于简单的原子标志操作,只有两个操作:`atomic_flag_test_and_set()`和`atomic_flag_clear()`。 2. 原子整型类型(如`atomic_int`、`atomic_uint`等):支持常见的整型操作,如赋值、加法、减法、比较交换等。 3. 原子指针类型(如`atomic_intptr_t`、`atomic_ptrdiff_t`等):支持指针类型的原子操作,如原子加载、存储和比较交换等。 4. `atomic_thread_fence()`函数:用于实现内存屏障,确保指令重排序不会破坏多线程程序的正确性。 5. `atomic_load()`和`atomic_store()`函数:用于原子加载和存储操作。 6. `atomic_exchange()`函数:用于原子交换操作,可以原子地交换一个值并返回旧值。 7. `atomic_compare_exchange_strong()`和`atomic_compare_exchange_weak()`函数:用于原子比较并交换操作,可以原子地比较并交换一个值。 通过使用这些原子类型和函数,我们可以实现线程安全的并发操作。注意,原子操作并不意味着完全的线程同步,额外的同步机制(如互斥锁)可能仍然是必需的来确保正确的并发访问。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mrbone11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值