muduo源码解析2-AtomicIntegerT类

AtomicIntegerT

template<typename T>
class atomicTntergerT:public noncopyable
{
};

作用:

与std::aotmic<int> 类似,主要实现对 int32_t 和 int64_t 类型的原子操作。

在内部并不是使用互斥锁实现原子性,而是利用__sync_val_compare_and_swap和__sync_fetch_and_add在内部实现原子操作。

成员变量:

private:
    volatile T m_value;

volatile防止编译器对该变量进行优化,即直接在内存中进行存取,而不是优化到寄存器中进行存取,主要是为了防止变量的值在内存中和寄存器中不一致。

成员函数:

public:
    atomicTntergerT():m_value(0){}
    T get()
    {
        return __sync_val_compare_and_swap(&m_value,0,0);
    }
    T getAndAdd(T x)
    {
        return __sync_fetch_and_add(&m_value,x);
    }
    T addAndGet(T x)
    {
        return __sync_add_and_fetch(&m_value,x);
    }
    T incrementAndGet()
    {
        return addAndGet(1);
    }
    T decrementAndGet()
    {
        return addAndGet(-1);
    }

    void add(T x)
    {
        getAndAdd(x);
    }
    void increment()
    {
        incrementAndGet();
    }
    void decrement()
    {
        decrementAndGet();
    }

    T getAndSet(T x)
    {
        return __sync_lock_test_and_set(&m_value,x);
    }

大多是常见的运算操作,只不过在这里全部实现了多线程环境下的原子操作。

测试:

计算任务:THREAD_NUM个线程让count++ NUM次
测试mutex,atomic和atomicInt64的性能
测试结果
mutex 2198041
atomic 346589
atomicInt64 345607

std::atomic和atomicInt64表现差不多.都比互斥锁要好一点

测试代码:

#include<iostream>
#include"base/timestamp.h"
#include"base/atomic.h"

#include<mutex>
#include<atomic>
#include<thread>

using namespace mymuduo;

#define NUM 200000
#define THREAD_NUM 100

std::mutex mutex;
long long count1=0;
std::atomic<int64_t> count2;
atomicInt64 count3;

void workerthread1()
{
    for(int i=0;i<NUM;i++)
    {
        mutex.lock();
        count1++;
        mutex.unlock();
    }
}

void workerthread2()
{
    for(int i=0;i<NUM;i++)
        count2++;
}

void workerthread3()
{
    for(int i=0;i<NUM;i++)
        count3.add(1);
}

void test_performance()
{
    timestamp t1(timestamp::now());
    std::thread t[THREAD_NUM];

    for(int i=0;i<THREAD_NUM;i++)
        t[i]=std::thread(workerthread1);

    for(int i=0;i<THREAD_NUM;i++)
        t[i].join();

    std::cout<<timestamp::now().microSecSinceEpoch()-t1.microSecSinceEpoch()<<" ";
    std::cout<<count1<<std::endl;

    t1=timestamp::now();
    for(int i=0;i<THREAD_NUM;i++)
        t[i]=std::thread(workerthread2);

    for(int i=0;i<THREAD_NUM;i++)
        t[i].join();
    std::cout<<timestamp::now().microSecSinceEpoch()-t1.microSecSinceEpoch()<<" ";
    std::cout<<count2<<std::endl;

    t1=timestamp::now();
    for(int i=0;i<THREAD_NUM;i++)
        t[i]=std::thread(workerthread3);

    for(int i=0;i<THREAD_NUM;i++)
        t[i].join();
    std::cout<<timestamp::now().microSecSinceEpoch()-t1.microSecSinceEpoch()<<" ";
    std::cout<<count3.get()<<std::endl;

}

int main()
{

    test_performance();

}

 

posted @ 2020-08-22 15:10  WoodInEast  阅读(102)  评论(0编辑  收藏  举报