C++原子类实现

引言

在系统实现的过程中,经常需要用到计数功能,为了多线程下的安全使用,我自己定义了一个原子类。

基于Mutex的实现

我基于Mutex实现了一个简单的原子类,代码如下

1/* 2 * 说明:自定义整数操作的原子类,减少代码中的各种锁 3 */ 4 5#ifndef _ATOMIC_INT64_H_ 6#define _ATOMIC_INT64_H_ 7 8 9#include <stdint.h> 10#include "mutex.h" 11 12 13 14template<class T> 15class AtomicInt 16{ 17public: 18 AtomicInt(T value_) : value(value_){}; 19 20 //自增长操作,返回增长前的值 21 void Increment(const T& step) 22 { 23 MutexGuard guard(mutex); 24 value += step; 25 } 26 27 28 T GetValue() 29 { 30 MutexGuard guard(mutex); 31 return value; 32 } 33 34 35 private: 36 T value; 37 Mutex mutex; 38 }; 39 40 #endif

如代码所示,这是一种最简单的原子类实现方式,基于系统提供的互斥量,实现对变量的互斥访问。

C++11下的原子锁

C++11本身提供了原子锁供我们使用,非常方便,我写代码测试了一下,确实有效。 测试代码采用多线程分别对atomic int类型和普通的整数类型进行自增操作。结果发现 atomic int结果正确,而普通int类型数据不正确。

1atomic_int32_t atomicintparam = 0; 2int32_t intparam = 0; 3void thread_atomic_test() 4{ 5 for (int i = 0; i < 10000; i++) 6 { 7 atomicintparam++; 8 intparam++; 9 } 10} 11 12void AtomicParamTest() 13{ 14 vector<thread*> threads; 15 for (int i = 0; i < 10; i++) 16 { 17 std::thread* task = new std::thread(thread_atomic_test); 18 threads.push_back(task); 19 } 20 21 for (thread* task : threads) 22 { 23 task->join(); 24 } 25 26 cout << "atomic int param: " << atomicintparam << endl; 27 cout << "common int param: " << intparam << endl; 28}

结果如下:

1atomic int param: 100000 2common int param: 86996

目前的情况是我们的编译器不支持C++11, 但是我觉得基于Mutex实现一个原子锁又过重。为了解惑,我做了一个测试,在10个线程的并发下对某个整数进行自增操作,加到1亿。测试下来的时间如下,单位毫秒:

1atomic int param: 100000000(自增次数) 2969 (时间) 2atomic int param: 100000000(自增次数) 13187(时间)

测试结果发现相差4倍左右,单线程加到1千万需要13s,我的场景里每个计数器计数不超过100,用mutex,还没有成为我的瓶颈,可以使用。

点赞
收藏

评论区

加载中...

相关推荐

java中多态的实现机制

多态的概念:  简单来说就是事物在运行过程中存在的不同状态,即父类或接口定义的引用变量指向子类或具体实现类的实例对象。程序调用方法在运行期才进行动态绑定,而不是引用变量的类型中定义的方法。多态存在的前提:1、存在继承关系,子类继承父类;2、子类重写父类的方法;3、父类引用指向子类对象。具体实例:1、定义一个父类:Animal

Java并发之ReentrantLock源码解析

Java并发之ReentrantLock源码解析Condition在上一章中,我们大概了解了Condition的使用,下面我们来看看Condition再juc的实现。juc下Condition本质上是一个接口,它只定义了这个接口的使用方式,具体的实现其实是交由子类完成。cpublicinterfaceConditionvoidawait()

Android模板设计模式之 - 构建整个应用的BaseActivity

1\.模式介绍模式的定义定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。所有分享大纲:视频讲解地址:模式的使用场景1.多个子类有公有的方法,并且逻辑基本相同时。2.重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。3.重构时,模板方法模式

Android-自定义view

要自定义view,都知道有3个方法需要重写:onMeasure、onLayout、onDraw。而且这三个方法的执行是按顺序的。生命周期image.png实际开发中,比较多的自定义都是具体实现一个view的子类,实现viewgroup的子类比较少,两者基本相似,区别就是view需要实现onMeasure、onLayout、onDraw三个方法,而vie

CGLIB介绍与原理(通过继承的动态代理)

一、什么是CGLIB?CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。二、CGLIB原理CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的

Java多线程基础

(1)传统使用类Thread和接口Runnable实现 1\.在Thread子类覆盖的run方法中编写运行代码方式一 newThread(){@Overridepublicvoidrun(){while(true){try{Thread.sleep(2