#ifndef _FF_CIRCLEQUEUE_H__ #define _FF_CIRCLEQUEUE_H__ #include #include #include #include #include #include #include #include "QueueStructDefine.h" using namespace std; template class FF_CircleQueue { public: /** * @brief Construct a new ff circlequeue object * * @param Size Circle Queue元素数量 * @param ElemArray 元素数组 */ FF_CircleQueue(int Size, T ElemArray); ~FF_CircleQueue(); /** * @brief 慢队列 入队 * * @param Elem * @return int */ int EnFullQueue(const T& Elem); /** * @brief 满队列 出队 * * @param Elem * @return int */ int DeFullQueue(T& Elem); /** * @brief 满队列尝试出对,如果此时队列为空,返回false,有数据返回true * * @param Elem * @return true * @return false */ bool Try_DeFullQueue(T& Elem); /** * @brief * * @param Elem * @return int */ int Peek_DeFullQueue(T& Elem); ///< 获取数据,但不出队 /** * @brief * * @param Elem * @return int */ int TryPeek_DeFullQueue(T& Elem); /** * @brief 空队列 入队 * * @param Elem * @return int */ int EnFreeQueue(const T& Elem); /** * @brief 空队列 出队 * * @param Elem * @return int */ int DeFreeQueue(T& Elem); /** * @brief 空队列尝试出对,有数据为true,无数据返回false * * @param Elem * @return true * @return false */ bool Try_DeFreeQueue(T& Elem); /** * @brief * * @return true * @return false */ bool IsValid(); /** * @brief 获取各队列所持有元素数量 * * @return unsigned int */ unsigned int GetFullQueueSize(); unsigned int GetFreeQueueSize(); private: void SetValid() { qValid = true; } void SetInvalid() { qValid = false; } bool qValid; int NumElem; /** * @brief 空队列,及其锁,条件变量 * */ std::queue free_queue_; pthread_mutexattr_t free_mutAttr_; pthread_mutex_t free_mutex_; pthread_cond_t free_condition_ = PTHREAD_COND_INITIALIZER; /** * @brief 满队列,及其锁,条件变量 * */ std::queue full_queue_; pthread_mutexattr_t full_mutAttr_; pthread_mutex_t full_mutex_; pthread_cond_t full_condition_ = PTHREAD_COND_INITIALIZER; }; /** * Implementation of Circle Queue, Designed by Derek. */ /** * @brief Construct a new queuemanager object * @tparam T * @param Size * @param ElemArray */ template FF_CircleQueue::FF_CircleQueue(int Size, T ElemArray) { qValid = false; NumElem = 0; /// Prevent invalid queue element if(Size==0 || ElemArray==NULL){ /// NULL } memset(&free_mutAttr_, 0, sizeof(pthread_mutexattr_t)); pthread_mutexattr_init(&free_mutAttr_); pthread_mutexattr_settype(&free_mutAttr_, PTHREAD_MUTEX_RECURSIVE_NP); pthread_mutex_init(&free_mutex_, &free_mutAttr_); memset(&full_mutAttr_, 0, sizeof(pthread_mutexattr_t)); pthread_mutexattr_init(&full_mutAttr_); pthread_mutexattr_settype(&full_mutAttr_, PTHREAD_MUTEX_RECURSIVE_NP); pthread_mutex_init(&full_mutex_, &full_mutAttr_); NumElem = Size; ///< Element size for(int i=0; i FF_CircleQueue::~FF_CircleQueue() { pthread_mutex_destroy(&free_mutex_); pthread_mutex_destroy(&full_mutex_); /// NULL } /** * @brief * @param Elem * @return int */ template int FF_CircleQueue::EnFullQueue(const T& Elem) ///< 入队 { pthread_mutex_lock(&full_mutex_); full_queue_.push(Elem); pthread_mutex_unlock(&full_mutex_); ///< 主动释放 pthread_cond_signal(&full_condition_); return 0; } /** * @brief * @param Elem * @return int */ template int FF_CircleQueue::DeFullQueue(T& Elem) ///< 出队 { pthread_mutex_lock(&full_mutex_); while (full_queue_.empty()) { pthread_cond_wait(&full_condition_, &full_mutex_); } Elem = full_queue_.front(); full_queue_.pop(); pthread_mutex_unlock(&full_mutex_); return 0; } /** * @brief * @param Elem * @return int */ template int FF_CircleQueue::Peek_DeFullQueue(T& Elem) ///< 获取数据,但不出队 { // *Elem = full_queue_.peek(); return 0; } /** * @brief * @tparam T * @param Elem * @return int */ template bool FF_CircleQueue::Try_DeFullQueue(T& Elem) { pthread_mutex_lock(&full_mutex_); if (full_queue_.empty()) { pthread_mutex_unlock(&full_mutex_); return false; } Elem = full_queue_.front(); full_queue_.pop(); pthread_mutex_unlock(&full_mutex_); return true; } /** * @brief * @tparam T * @param Elem * @return int */ template int FF_CircleQueue::TryPeek_DeFullQueue(T& Elem) { //bool ret = false; pthread_mutex_lock(&full_mutex_); if (full_queue_.empty()) { pthread_mutex_unlock(&full_mutex_); return -1; } Elem = full_queue_.front(); pthread_mutex_unlock(&full_mutex_); return 0; } /** * @brief * @param Elem * @return int */ template int FF_CircleQueue::EnFreeQueue(const T& Elem) { pthread_mutex_lock(&free_mutex_); free_queue_.push(Elem); pthread_mutex_unlock(&free_mutex_); ///< 主动释放 pthread_cond_signal(&free_condition_); return 0; } /** * @brief * @param Elem * @return int */ template int FF_CircleQueue::DeFreeQueue(T& Elem) { pthread_mutex_lock(&free_mutex_); while (free_queue_.empty()) { pthread_cond_wait(&free_condition_, &free_mutex_); } Elem = free_queue_.front(); free_queue_.pop(); pthread_mutex_unlock(&free_mutex_); return 0; } /** * @brief * @tparam T * @param Elem * @return int */ template bool FF_CircleQueue::Try_DeFreeQueue(T& Elem) { pthread_mutex_lock(&free_mutex_); if (free_queue_.empty()) { pthread_mutex_unlock(&free_mutex_); return false; } Elem = free_queue_.front(); free_queue_.pop(); pthread_mutex_unlock(&free_mutex_); return true; } /** * @brief Check if queue manager is valid * @return true * @return false */ template bool FF_CircleQueue::IsValid() { return qValid; } /** * @brief Get the number of elements in the fullqueue * @tparam T * @return int */ template unsigned int FF_CircleQueue::GetFullQueueSize() { return full_queue_.size(); } /** * @brief Get the number of elements in the freequeue * @tparam T * @return int */ template unsigned int FF_CircleQueue::GetFreeQueueSize() { return free_queue_.size(); } template class FF_CircleQueue; ///< TEST template class FF_CircleQueue; ///< TEST template class FF_CircleQueue; ///< TEST // int fun(); /////////////////////////////////////////////////////////////////////////////////// #endif ///_FF_QUEUE_MANAGER_H__