|  | @@ -9,10 +9,12 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * @brief 这里采用零公摊的方式,设置多大的空间,就有多大的空间可以使用
 | 
	
		
			
				|  |  | - *        1、如果队列是空,m_rear和m_front都设置为-1
 | 
	
		
			
				|  |  | - *        2、m_rear指向最新入队的元素的下一个位置
 | 
	
		
			
				|  |  | - *        3、m_front指向需要出队的第一个元素
 | 
	
		
			
				|  |  | - *        4、环形队列自带互斥锁
 | 
	
		
			
				|  |  | + *        1、m_rear指向最新入队的元素的下一个位置,就是下个将要入队的元素位置
 | 
	
		
			
				|  |  | + *        2、m_front指向需要出队的第一个元素
 | 
	
		
			
				|  |  | + *        3、环形队列自带互斥锁
 | 
	
		
			
				|  |  | + *        
 | 
	
		
			
				|  |  | + * 注意:
 | 
	
		
			
				|  |  | + *      使用时要注意,不带NoBlock的都是阻塞函数
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * 判断队列满:
 | 
	
		
			
				|  |  |   *        m_rear == m_front,并且此时都不等于 -1
 | 
	
	
		
			
				|  | @@ -32,7 +34,7 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  |  class RingQueue
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | +{    
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  public:
 | 
	
		
			
				|  |  |      RingQueue();
 | 
	
	
		
			
				|  | @@ -45,22 +47,28 @@ public:
 | 
	
		
			
				|  |  |      /* 清空队列 */
 | 
	
		
			
				|  |  |      void clearQueue();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* 入队 */
 | 
	
		
			
				|  |  | -    bool enQueue(const T& data);
 | 
	
		
			
				|  |  | -    bool enQueue(T&& data);
 | 
	
		
			
				|  |  | -    /* 阻塞入队 */
 | 
	
		
			
				|  |  | -    void enQueueBlock(const T& data);
 | 
	
		
			
				|  |  | -    /* 出队 */
 | 
	
		
			
				|  |  | -    bool deQueue(T& data);
 | 
	
		
			
				|  |  | -    /* 阻塞出队 */
 | 
	
		
			
				|  |  | -    T deQueueBlock();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* 获取队列中第一个值(下一个出队的元素),但是不出队,非阻塞 */
 | 
	
		
			
				|  |  | -    bool front(T& t);
 | 
	
		
			
				|  |  | -    T& frontBlock();
 | 
	
		
			
				|  |  | -    /* 获取队列中即将入队的位置(这个函数用于存储指针的环形队列,获取内存地址) */
 | 
	
		
			
				|  |  | -    T& backBlock();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +    /* 入队,默认是阻塞入队 */
 | 
	
		
			
				|  |  | +    void push(const T& value);
 | 
	
		
			
				|  |  | +    void push(T&& value);
 | 
	
		
			
				|  |  | +    bool push_NoBlock(const T& value);
 | 
	
		
			
				|  |  | +    bool push_NoBlock(T&& value);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /* 出队,删除队列的首个元素
 | 
	
		
			
				|  |  | +     * 注意,如果存储的是指针,需要手动释放该指针指向的内存区域,不然会造成内存泄漏 */
 | 
	
		
			
				|  |  | +    void pop();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /* 获取队列中第一个值),但是不出队
 | 
	
		
			
				|  |  | +     * 阻塞的方式获取,如果队列为空,会一直阻塞住,直到获取到数据为止 */
 | 
	
		
			
				|  |  | +    T front();
 | 
	
		
			
				|  |  | +    /* 非阻塞的方式获取,队列为空返回false */
 | 
	
		
			
				|  |  | +    bool front_NoBlock(T& t);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /* 获取对立第一个数据,获取完立刻出队
 | 
	
		
			
				|  |  | +     * 如果队列为空,会阻塞住,直到有数据为止 */
 | 
	
		
			
				|  |  | +    T&& front_pop();
 | 
	
		
			
				|  |  | +    // T&& front_pop_rvalue();
 | 
	
		
			
				|  |  | +    bool front_pop_NoBlock(T& t);
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  |      /* 获取队列大小,队列中有效值的大小 */
 | 
	
		
			
				|  |  |      long getQueueSize();
 | 
	
		
			
				|  |  |      /* 获取队列容量 */
 | 
	
	
		
			
				|  | @@ -69,15 +77,18 @@ public:
 | 
	
		
			
				|  |  |      bool isEmpty();
 | 
	
		
			
				|  |  |      /* 判断队列是否已满 */
 | 
	
		
			
				|  |  |      bool isFull();
 | 
	
		
			
				|  |  | +    /* 退出所有可能的阻塞函数 */
 | 
	
		
			
				|  |  | +    void exit();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  private:
 | 
	
		
			
				|  |  | +    bool m_isExit = false;                  /* 是否退出,这个标识位是为了退出阻塞住的函数 */
 | 
	
		
			
				|  |  |      std::mutex m_mutex;                     /* 互斥锁 */
 | 
	
		
			
				|  |  |      T* m_queue = nullptr;                   /* 队列 */
 | 
	
		
			
				|  |  |      long m_capacity = 0;     /* 队列容量 */
 | 
	
		
			
				|  |  |      long m_front = 0;        /* 队头 */
 | 
	
		
			
				|  |  |      long m_rear = 0;         /* 队尾 */
 | 
	
		
			
				|  |  | -    std::condition_variable m_cond_NoFull;      /* 非空条件变量 */
 | 
	
		
			
				|  |  | -    std::condition_variable m_cond_NoEmpty;     /* 非满条件变量 */
 | 
	
		
			
				|  |  | +    std::condition_variable m_cond_NoFull;      /* 非满条件变量 */
 | 
	
		
			
				|  |  | +    std::condition_variable m_cond_NoEmpty;     /* 非空条件变量 */
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -149,167 +160,236 @@ void RingQueue<T>::clearQueue()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* 入队 */
 | 
	
		
			
				|  |  | +/*************** 入队 *******************/
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  | -bool RingQueue<T>::enQueue(const T& data)
 | 
	
		
			
				|  |  | +void RingQueue<T>::push(const T& value)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    m_mutex.lock();
 | 
	
		
			
				|  |  | -    /* 先检查队列是否还有剩余空间 */
 | 
	
		
			
				|  |  | -    if(isFull())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | +        std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        m_cond_NoFull.wait(lock, [this](){
 | 
	
		
			
				|  |  | +            return (!isFull() || m_isExit);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        if(m_isExit)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(m_rear == -1)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_front = 0;
 | 
	
		
			
				|  |  | +            m_rear = 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        m_queue[m_rear] = value;
 | 
	
		
			
				|  |  | +        m_rear = (m_rear + 1) % m_capacity;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    else if(m_rear == -1)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        m_front = 0;
 | 
	
		
			
				|  |  | -        m_rear = 0;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /* 数据入队 */
 | 
	
		
			
				|  |  | -    m_queue[m_rear] = data;
 | 
	
		
			
				|  |  | -    m_rear = (m_rear + 1) % m_capacity;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    m_mutex.unlock();
 | 
	
		
			
				|  |  |      m_cond_NoEmpty.notify_all();
 | 
	
		
			
				|  |  | -    return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* 入队,传入右值 */
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  | -bool RingQueue<T>::enQueue(T&& data)
 | 
	
		
			
				|  |  | +void RingQueue<T>::push(T&& value)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    m_mutex.lock();
 | 
	
		
			
				|  |  | -    /* 先检查队列是否还有剩余空间 */
 | 
	
		
			
				|  |  | -    if(isFull())
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if(m_rear == -1)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        m_front = 0;
 | 
	
		
			
				|  |  | -        m_rear = 0;
 | 
	
		
			
				|  |  | +        std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        m_cond_NoFull.wait(lock, [this](){
 | 
	
		
			
				|  |  | +            return (!isFull() || m_isExit);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        if(m_isExit)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(m_rear == -1)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_front = 0;
 | 
	
		
			
				|  |  | +            m_rear = 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        m_queue[m_rear] = std::move(value);
 | 
	
		
			
				|  |  | +        m_rear = (m_rear + 1) % m_capacity;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    m_queue[m_rear] = std::move(data);
 | 
	
		
			
				|  |  | -    m_rear = (m_rear + 1) % m_capacity;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    m_mutex.unlock();
 | 
	
		
			
				|  |  |      m_cond_NoEmpty.notify_all();
 | 
	
		
			
				|  |  | -    return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* 阻塞入队 */
 | 
	
		
			
				|  |  | -template<typename T>
 | 
	
		
			
				|  |  | -void RingQueue<T>::enQueueBlock(const T& data)
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * @brief 非阻塞的方式入队,如果队列已满,直接返回
 | 
	
		
			
				|  |  | + * 
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | + template<typename T>
 | 
	
		
			
				|  |  | +bool RingQueue<T>::push_NoBlock(const T& value)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | -    m_cond_NoFull.wait(lock, [this](){
 | 
	
		
			
				|  |  | -        return !isFull();
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if(m_rear == -1)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        m_front = 0;
 | 
	
		
			
				|  |  | -        m_rear = 0;
 | 
	
		
			
				|  |  | +        // std::unique_lock<std::mutex> lock(m_mutex, std::defer_lock);
 | 
	
		
			
				|  |  | +        // if(!lock.try_lock())
 | 
	
		
			
				|  |  | +        // {
 | 
	
		
			
				|  |  | +        //     return false;
 | 
	
		
			
				|  |  | +        // }
 | 
	
		
			
				|  |  | +        std::lock_guard<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        /* 先检查队列是否还有剩余空间 */
 | 
	
		
			
				|  |  | +        if(isFull())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if(m_rear == -1)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_front = 0;
 | 
	
		
			
				|  |  | +            m_rear = 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        m_queue[m_rear] = value;
 | 
	
		
			
				|  |  | +        m_rear = (m_rear + 1) % m_capacity;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    m_queue[m_rear] = data;
 | 
	
		
			
				|  |  | -    m_rear = (m_rear + 1) % m_capacity;
 | 
	
		
			
				|  |  | -    m_mutex.unlock();
 | 
	
		
			
				|  |  |      m_cond_NoEmpty.notify_all();
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* 出队 */
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  | -bool RingQueue<T>::deQueue(T& data)
 | 
	
		
			
				|  |  | +bool RingQueue<T>::push_NoBlock(T&& value)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    m_mutex.lock();
 | 
	
		
			
				|  |  | -    if(isEmpty())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | +        // std::unique_lock<std::mutex> lock(m_mutex, std::defer_lock);
 | 
	
		
			
				|  |  | +        // if(!lock.try_lock())
 | 
	
		
			
				|  |  | +        // {
 | 
	
		
			
				|  |  | +        //     return false;
 | 
	
		
			
				|  |  | +        // }
 | 
	
		
			
				|  |  | +        std::lock_guard<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        /* 先检查队列是否还有剩余空间 */
 | 
	
		
			
				|  |  | +        if(isFull())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if(m_rear == -1)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_front = 0;
 | 
	
		
			
				|  |  | +            m_rear = 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        m_queue[m_rear] = std::move(value);
 | 
	
		
			
				|  |  | +        m_rear = (m_rear + 1) % m_capacity;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    data = std::move(m_queue[m_front]);
 | 
	
		
			
				|  |  | +    m_cond_NoEmpty.notify_all();
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /* 判断队列是否为空了 */
 | 
	
		
			
				|  |  | -    m_front = (m_front + 1) % m_capacity;
 | 
	
		
			
				|  |  | -    if(m_front == m_rear)
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * @brief 出队,删除队列的首个元素
 | 
	
		
			
				|  |  | + *        注意,如果存储的是指针,需要手动释放该指针指向的内存区域,不然会造成内存泄漏
 | 
	
		
			
				|  |  | + * 
 | 
	
		
			
				|  |  | + * @tparam T 
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +template<typename T>
 | 
	
		
			
				|  |  | +void RingQueue<T>::pop()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        m_front = -1;
 | 
	
		
			
				|  |  | -        m_rear = -1;
 | 
	
		
			
				|  |  | +        std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        if(isEmpty())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        m_front = (m_front + 1) % m_capacity;
 | 
	
		
			
				|  |  | +        if(m_front == m_rear)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_front = -1;
 | 
	
		
			
				|  |  | +            m_rear = -1;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    m_mutex.unlock();
 | 
	
		
			
				|  |  |      m_cond_NoFull.notify_all();
 | 
	
		
			
				|  |  | -    return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* 出队 */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* 获取队列中第一个值,但是不出队
 | 
	
		
			
				|  |  | + * 阻塞的方式获取,如果队列为空,会一直阻塞住,直到获取到数据为止 */
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  | -T RingQueue<T>::deQueueBlock()
 | 
	
		
			
				|  |  | +T RingQueue<T>::front()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | -    m_cond_NoEmpty.wait(lock, [this](){
 | 
	
		
			
				|  |  | -        return !isEmpty();
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    long tmp = m_front;
 | 
	
		
			
				|  |  | -    m_front = (m_front + 1) % m_capacity;
 | 
	
		
			
				|  |  | -    if(m_front == m_rear)
 | 
	
		
			
				|  |  | +    T retValue;
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        m_front = -1;
 | 
	
		
			
				|  |  | -        m_rear = -1;
 | 
	
		
			
				|  |  | +        std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        m_cond_NoEmpty.wait(lock, [this](){
 | 
	
		
			
				|  |  | +            return (!isEmpty() || m_isExit);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        if(m_isExit)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return retValue;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        retValue = m_queue[m_front];
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    auto ret = m_queue[tmp];
 | 
	
		
			
				|  |  | -    m_cond_NoFull.notify_all();
 | 
	
		
			
				|  |  | -    return ret;
 | 
	
		
			
				|  |  | +    return retValue;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* 获取队列中第一个值(下一个出队的元素),但是不出队,非阻塞 */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* 获取队列中第一个值,但是不出队,非阻塞的方式获取 */
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  | -bool RingQueue<T>::front(T& t)
 | 
	
		
			
				|  |  | +bool RingQueue<T>::front_NoBlock(T& t)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    std::lock_guard<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | -    if(isEmpty())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | +        std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        if(isEmpty())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        t = m_queue[m_front];
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    t = m_queue[m_front];
 | 
	
		
			
				|  |  |      return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* 阻塞获取队列中第一个数据,但是不出队 */
 | 
	
		
			
				|  |  | +/* 获取对立第一个数据,获取完立刻出队
 | 
	
		
			
				|  |  | + * 如果队列为空,会阻塞住,直到有数据为止 */
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  | -T& RingQueue<T>::frontBlock()
 | 
	
		
			
				|  |  | +T&& RingQueue<T>::front_pop()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    std::lock_guard<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | -    m_cond_NoEmpty.wait(lock, [this](){
 | 
	
		
			
				|  |  | -        return !isEmpty();
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -    return m_queue[m_front];
 | 
	
		
			
				|  |  | +    T ret;
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        m_cond_NoEmpty.wait(lock, [this](){
 | 
	
		
			
				|  |  | +            return (!isEmpty() || m_isExit);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        if(m_isExit)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return std::move(ret);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        ret = std::move(m_queue[m_front]);
 | 
	
		
			
				|  |  | +        m_front = (m_front + 1) % m_capacity;
 | 
	
		
			
				|  |  | +        if(m_front == m_rear)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_front = -1;
 | 
	
		
			
				|  |  | +            m_rear = -1;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    m_cond_NoFull.notify_all();
 | 
	
		
			
				|  |  | +    return std::move(ret);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/**
 | 
	
		
			
				|  |  | - * @brief 获取队列中即将入队的位置(这个函数用于存储指针的环形队列,获取内存地址)
 | 
	
		
			
				|  |  | - *        这个函数不一定内存安全,谨慎使用
 | 
	
		
			
				|  |  | - * 
 | 
	
		
			
				|  |  | - * @tparam T 
 | 
	
		
			
				|  |  | - * @return T& 
 | 
	
		
			
				|  |  | - */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  | -T& RingQueue<T>::backBlock()
 | 
	
		
			
				|  |  | +bool RingQueue<T>::front_pop_NoBlock(T& t)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    std::lock_guard<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | -    m_cond_NoFull.wait(lock, [this](){
 | 
	
		
			
				|  |  | -        return !isFull();
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    return m_queue[m_rear];
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::unique_lock<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  | +        if(isEmpty())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        t = std::move(m_queue[m_front]);
 | 
	
		
			
				|  |  | +        m_front = (m_front + 1) % m_capacity;
 | 
	
		
			
				|  |  | +        if(m_front == m_rear)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            m_front = -1;
 | 
	
		
			
				|  |  | +            m_rear = -1;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    m_cond_NoFull.notify_all();
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /* 获取队列中有效值的大小 */
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  |  long RingQueue<T>::getQueueSize()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +    std::lock_guard<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  |      if(m_rear == -1)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          return 0;
 | 
	
	
		
			
				|  | @@ -330,6 +410,7 @@ long RingQueue<T>::getQueueSize()
 | 
	
		
			
				|  |  |  template<typename T>
 | 
	
		
			
				|  |  |  long RingQueue<T>::getQueueCapacity()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +    std::lock_guard<std::mutex> lock(m_mutex);
 | 
	
		
			
				|  |  |      return m_capacity;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -372,7 +453,14 @@ bool RingQueue<T>::isFull()
 | 
	
		
			
				|  |  |      return false;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +/* 退出所有可能的阻塞函数 */
 | 
	
		
			
				|  |  | +template<typename T>
 | 
	
		
			
				|  |  | +void RingQueue<T>::exit()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    m_isExit = true;
 | 
	
		
			
				|  |  | +    m_cond_NoFull.notify_all();
 | 
	
		
			
				|  |  | +    m_cond_NoEmpty.notify_all();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |