当前位置: 首页 > news >正文

《C++11 基于CAS无锁操作的atomic原子类型》

count++;
count--;

我们知道,++/--操作并不是原子性的,其实对应三条汇编指令来完成的。

  • 读取:从内存中把变量的值读取到寄存器
  • 修改:在寄存器里将变量的值+1/-1
  • 写入:把修改后的值写入到内存

在单线程环境下,这三个步骤是顺序执行的不会有问题。但是在多线程环境下,多个线程可能对同一个变量同时进行++/--操作,从而导致数据竞争的问题。

可以看下面的过程演示。

一:

二:

三:

C++11是通过加锁来保证++/--操作的原子性的。

std::lock_guard<std::mutext>(mtx);
count++;
std::unlock_guard<std::mutex>(mtx);

互斥锁是比较重的,临界区代码稍稍复杂的情况下建议使用。从系统理论上来讲,使用CAS无锁操作来保证++/--操作的原子性就足够了,其实并不是不加锁,只是不在软件层面上加锁解锁,而是在硬件层面上实现的。

#include<iostream>
#include<thread>
#include<list>
#include<atomic>
using namespace std;

volatile std::atomic_bool isReady = false;
volatile std::atomic_int myCount = 0;

void task()
{
	while (!isReady)
	{
		std::this_thread::yield(); // 线程让出当前的CPU时间片,等待下一次调度
	}

	for (int i = 0; i < 100; i++)
	{
		myCount++;
	}
}
int main()
{
	list<std::thread> tlist;
	for (int i = 0; i < 10; i++)
	{
		tlist.push_back(std::thread(task));
	}

	std::this_thread::sleep_for(std::chrono::seconds(3));
	isReady = true;
	
	for (auto& t : tlist)
	{
		t.join();
	}
	std::cout << "myCount: " << myCount << std::endl;

	return 0;
}

相关文章:

  • 头歌 JAVA 桥接模式实验
  • UI数据处理新隐私保护:确保用户新信息安全
  • 固定公网 IP
  • 【浙大PTA:L1系列题目】
  • NFS 安装与测试
  • 如何在SQL中高效使用聚合函数、日期函数和字符串函数:实用技巧与案例解析
  • 001 你好LabVIEW
  • 如何理解java中Stream流?
  • 对IKFOM论文中一些关键内容的理解
  • github如何为开源项目作出贡献
  • 高防ip和高防服务器的区别?
  • MSE分类时梯度消失的问题详解和交叉熵损失的梯度推导
  • 高能ISP模块功能说明
  • SQL优化主要有哪些方式
  • 技术与情感交织的一生 (二)
  • 关于神经网络中的激活函数
  • Burp Suite 代理配置全流程指南
  • IDEA导入jar包后提示无法解析jar包中的类,比如无法解析符号 ‘log4j‘
  • 【Python-OpenCV】手势控制贪吃蛇
  • 水一个人的时候
  • 龚正市长调研闵行区,更加奋发有为地稳增长促转型,久久为功增强发展后劲
  • 共建医学人工智能高地,上海卫健委与徐汇区将在这些方面合作
  • 因港而兴,“长江黄金水道”上的宜宾故事
  • 特朗普促卡塔尔说服伊朗放弃核计划,伊朗总统:你来吓唬我们?
  • 因存在安全隐患,福特公司召回约27.4万辆SUV
  • 深圳拟出让3宗居住用地,共计用地面积6.77公顷