linux c++循環緩衝區模板類

一:概述ios

實際學習和工做中,咱們常常會遇到讀寫大量數據的狀況,這個時候咱們可能就用到了循環緩衝區。學習

循環緩衝區在處理大量數據的時候有很大的優勢,循環緩衝區在一些競爭問題上提供了一種免鎖的機制,免鎖的前提是,生產者和消費都只有一個的狀況下,不然也要加鎖。測試

二:循環緩衝區的實現理論以下圖spa

三:實現代碼以下所示:3d

//CRecycleQueue.h

#include<iostream>

//循環緩衝區類模板
template<class T>
class CRecycleQueue{

    private:
        //循環緩衝區地址指針
        T **_queue;
        //循環緩衝區讀遊標 (讀的位置)
        int _read;
        //循環緩衝區寫遊標 (寫的位置)
        int _write;
        //循環緩衝區的大小
        int _size;
        //咱們姑且稱這個變量爲掩碼,接下來用來做位&運算,從而實現循環緩衝
        int _mask;
        
    public:
        CRecycleQueue(){    
            _queue = NULL;
            _read = 0;
            _write = 0;
            _size = 0;
            _mask = 0;
        }
        //初始化循環緩衝區
        bool InitRecycleQueue(int exp){
            
            if(0 > exp){

                return false;
            }

            _read = 0;
            _write = 0;
            //傳進來一個整數,對1進行位移操做
            //好比exp = 4
            //_size的二進制表示:1000
            _size = 1 << exp;
            //_mask的二進制表示:0111
            _mask = _size - 1;
            //分配緩衝區空間
            _queue = (T **)new char[sizeof (T *) * _size];

            if(NULL == _queue){

                return false;
            }

            return true;            
        }
/*
 *    size = 1000  mask = 0111
 *  write或read同mask 做&運算,能夠實現循環緩衝區的功能
 *  也許你會問這裏爲何不使用 % 運算實現循環的循環功能呢?
 *  答案是系統 & 運算效率要比 % 運算效率高
 *
 *    Push:
 *        write = 0;
 *            0000 & 0111 = 0; write++ (寫入緩衝隊列的第0位置)
 *        write = 1;
 *            0001 & 0111 = 1; write++ (寫入緩衝隊列的第1位置)
 *        write = 2;
 *            0010 & 0111 = 2; write++
 *        write = 3;
 *            0011 & 0111 = 3; write++
 *        ...
 *        write = 8;
 *            1000 & 0111 = 0; write++
 *        write = 9;
 *            1001 & 0111 = 1; write++
 *        ...
 *
 *    Pop:
 *        read = 0;
 *            0000 & 0111 = 0; read++ (讀取緩衝隊列的第0位置的數據)
 *        read = 1;
 *             0001 & 0111 = 1; read++ (讀取緩衝隊列的第1位置的數據)
 *         read = 2;
 *             0010 & 0111 = 2; read++
 *         read = 3
 *            0011 & 0111 = 3; read++
 *        ...
 *        read = 8;
 *            1000 & 0111 = 0; read++
 *        ...
 * */
        
        bool Push(T *type){
            
            if(NULL == type){

                return false;
            }
            //當條件不知足的時候,說明緩衝區已滿,Push進來的數據就會丟失
            if(_write < _read + _size){
                //咱們這裏存入的是type指針,這個指針指向了一個咱們分配的內存空間或者類
                _queue[_write & _mask] = type;
                _write++;
                return true;
            }

            return false;
        }    

        T *Pop(){

            T *tmp = NULL;
            //當條件不知足的時候說明緩衝區已經沒有數據
            if(_read < _write){
                //取出隊列的數據
                tmp = _queue[_read & _mask];
                _read++;
            }

            return tmp;
        }
        
        int GetRemainSize(){

            return (_write - _read);
        }
};

下面是簡單的測試代碼:指針

//main.cpp

#include <iostream>
#include <pthread.h>
#include "CRecycleQueue.h"
using namespace std;

class UserInfo{

    private :
        int _num;
    
    public:
        UserInfo(int num){

            _num = num;
        }

        int getUserNum(){

            return _num;
        }
};

CRecycleQueue<UserInfo> *queue = new CRecycleQueue<UserInfo>;

void *write_func(void *args){

    int num = 0;
    while(1){

        //UserInfo裏能夠封裝你本身想要的數據
        //這裏僅僅是一個簡單的測試用例    
        UserInfo *info = new UserInfo(num++);

        if(!queue->Push(info)){
            //Push失敗 刪除手動分配的內存空間    
            delete info;
        }
        sleep(1);
    }
}

void *read_func(void *args){

    while(1){

        UserInfo *info = NULL;
        if(info = queue->Pop()){

            cout<<info->getUserNum()<<endl;
            delete info;
        }
        sleep(1);
    }
}
int 
main(){

    queue->InitRecycleQueue(8);

    pthread_t pid1;
    pthread_t pid2;
    //這種生產者和消費者都只有一個的狀況下,這個循環緩衝區爲競爭問題提供了免鎖,大大提升了程序的處理效率
    pthread_create(&pid1,NULL,read_func,NULL);
    pthread_create(&pid2,NULL,write_func,NULL);

    pthread_join(pid1,NULL);
    pthread_join(pid2,NULL);
    
    return 0;
}

編譯:g++ main.cpp -lpthread -o testcode

這個循環緩衝隊列大致的功能已經實現,其中循環緩衝隊列一些其餘操做並無去實現,只是描述了一些核心的操做!blog

若是有錯誤和其餘意見,提出來你們一塊兒相互討論和學習!隊列

相關文章
相關標籤/搜索