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

《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;
}


http://www.kler.cn/a/595166.html

相关文章:

  • Linux基础开发工具——gdb/cgdb(7)
  • AI风向标《AI与视频制作全攻略:从入门到精通实战课程》
  • 多无人车协同探索开源包启动文件介绍(上)
  • k8s中service概述(二)NodePort
  • 加速还是安全?CDN与群联云防护的本质差异与适用场景
  • Blender标注工具
  • Webrtc编译官方示例实现视频通话
  • 【初探数据结构】二叉树的顺序结构——堆的实现详解(上下调整算法的时间复杂度分析)
  • 10-STL、位运算、常用函数库
  • filebeat和logstash区别
  • Mysql Innodb引擎执行过程
  • Day11 动态规划入门
  • 又双叒叕Scrapy爬虫相关的面试题及详细解答
  • 【React】基于自定义Hook提取公共逻辑
  • 记一次线上SQL死锁事故
  • 【数据结构】栈(Stack)、队列(Queue)、双端队列(Deque) —— 有码有图有真相
  • 深入Python C API:掌握常用函数与实战技巧
  • NAT 实验:多私网环境下 NAPT、Easy IP 配置及 FTP 服务公网映射
  • Python与命令行参数
  • 关于Flask框架30道面试题及解析