循环队列实现

1、使用背景

假设有N个数据采集线程负责采集数据,有1个入库线程负责往数据库写数据,由于采集线程和入库线程是异步的,所以中间需要一个缓存区来作为采集线程和入库线程之间通信的桥梁,所以引入了循环队列。

2、N:1型场景

假设有N个采集线程,1个入库线程,架构图如下:

注意:

(1)由于采集线程入队时,操作的是队尾,有N个线程同时操作队尾,所以需要对这N个采集线程上锁(任何时刻只有一个采集线程在入队操作)

(2)而入库线程只有一个,同时呢,入库线程操作的是对头,和采集线程互不干涉,所以入库线程在入库时不需要上锁

3、循环队列代码实现

#ifndef __CQUEUE_H__
#define __CQUEUE_H__

#include <iostream>

using namespace std;

template <class T>
class CCircleQueue
{ 
public:
    CCircleQueue(int size)
    {
        data_ = new T[size] ;
        if(data_)
        {
            size_ = size;
            head_ = 0;
            tail_ = 0;
        }
        else
        {
            size_ = 0;
            head_ = 0;
            tail_ = 0;
        }
    }
    ~CCircleQueue()
    {
        delete []data_;
        data_ = 0;
    }

    int	size()
    {
        if(head_ == tail_)//队列为空
            return 0;
        else if(tail_>head_)
            return tail_-head_;
        else
            return (size_-head_+tail_) ;
    }

    int space()
    {
        return size_ - size() - 1;//少使用一个元素
    }

    void empty()
    {
        head_ = 0;
        tail_ = 0;
    }

    int	pop_front_n(T* data_buf, int buf_size)
    {
        int n = size();
        if(n==0)
        {
            cout << "The queue is empty." <<endl;
            return 0;
        }

        if(n > buf_size)
            n = buf_size ;

        for(int i=0; i<n; i++)
        {
            data_buf[i] = data_[head_];
            head_ = ((head_+1)%size_);
        }

        return n;
    }

    int push_back_n(T* data_buf, int buf_size)
    {
        int n = space();
        if(n==0)
        {
            cout << "The queue is full." <<endl;
            return 0;
        }

        if(n > buf_size)
            n = buf_size ;

        for(int i=0; i<n; i++)
        {
            data_[tail_] = data_buf[i];
            tail_ = ((tail_+1)%size_);
        }
        return n ;
    }

    bool push_back(T& val)
    {
        if(space() > 0 )
        {
            data_[tail_] = val ;
            tail_ = ((tail_+1)%size_);
            return true;
        }
        else{
            cout << "The queue is full." << endl;

            return false ;
        }
    }

private:
    int		size_;
    int		head_;
    int		tail_;

    T*	data_ ;
};
#endif

发布了200 篇原创文章 · 获赞 37 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/wo198711203217/article/details/98596820