队列问题,高分求建议
我现在设计了个FIFO队列,队列里存储的都是指针,先存进来的先出去,并将POP出去的位置和PUSH进来的位置记录下来,当这个位置到达队列末尾时,自动置于队首,现在队列存放的都是如下结构体
- C/C++ code
#define MSG_LEN 1024typedef struct Msg{ char state; short uCmdNo; //msg type short uLenth; //msg will be received short uDoneLen; //length of received int nSock; char msg[MSG_LEN]; //msg data}Msg, *pMsg;
我现在想从队列里检索出msg的sock为2的元素,并将其弹出,有没有什么合适的方法,还是将这个队列改为链表?
贴出代码
- C/C++ code
#ifndef FSTQUEUEMANAGER_H#define FSTQUEUEMANAGER_H#include "PublicDefine.h"#include <pthread.h>class FSTQueueManager{public: FSTQueueManager(int size); ~FSTQueueManager(void); inline bool isEmpty() const { return !m_nElements; } inline bool isFull() const { return m_nBounds == m_nElements; } inline int size() const { return m_nElements; } bool push(void* data); bool pop(void** data); bool tryPush(void* data); bool tryPop(void** data); bool interruptAll(); bool terminall();private: int m_nElements; int m_nIn; int m_nOut; int m_nBounds; int m_nFullWaiters; int m_nEmptyWaiters; void** m_pData; bool m_bTerminate; FST_COND m_pEmptyCond; FST_COND m_pFullCond; FST_MUTEX m_pMutex;};#endif //FSTQUEUEMANAGER_H
- C/C++ code
#include "FSTQueueManager.h"#include "PublicIncl.h"FSTQueueManager::FSTQueueManager(int size) :m_nBounds(size),m_nIn(0),m_nOut(0),m_nElements(0),m_nEmptyWaiters(0),m_nFullWaiters(0),m_bTerminate(false){ m_pData = (void**)malloc(size * sizeof(void*)); FST_MUTEX_INIT(&m_pMutex); FST_COND_INIT(&m_pFullCond); FST_COND_INIT(&m_pEmptyCond); }bool FSTQueueManager::push(void* data){ if(m_bTerminate) { return false; } //LOG_MSG("bound:%d elements:%d", m_nBounds, m_nElements); FST_LOCK(&m_pMutex); while (isFull() && !m_bTerminate) { LOG_MSG("full"); m_nFullWaiters ++; FST_WAIT(&m_pFullCond, &m_pMutex); m_nFullWaiters --; } /* queue is terminated */ if (m_bTerminate) { FST_UNLOCK(&m_pMutex); return false; } m_pData[m_nIn] = data; m_nIn = (m_nIn + 1) % m_nBounds; m_nElements ++; if(m_nEmptyWaiters) { FST_WAKE(&m_pEmptyCond); } FST_UNLOCK(&m_pMutex); // LOG_MSG("elements:%d, max:%d", m_nElements, m_nBounds); return true;}bool FSTQueueManager::pop(void** data) { /* no more elements ever again */ if (m_bTerminate) { return false; } /* ** Keep waiting until we wake up and ** find that the queue is not empty. */ FST_LOCK(&m_pMutex); while(isEmpty() && !m_bTerminate) { m_nEmptyWaiters ++; FST_WAIT(&m_pEmptyCond, &m_pMutex); m_nEmptyWaiters --; } /* queue is terminated */ if(m_bTerminate) { FST_UNLOCK(&m_pMutex); return false; } *data = m_pData[m_nOut]; m_nElements --; m_nOut = (m_nOut + 1) % m_nBounds; /* notify waiter if any */ if (m_nFullWaiters) { FST_WAKE(&m_pFullCond); } FST_UNLOCK(&m_pMutex); return true;}bool FSTQueueManager::tryPush(void* data){ /* no more elements ever again */ if (m_bTerminate) { return false; } FST_LOCK(&m_pMutex); if(isFull()) { FST_UNLOCK(&m_pMutex); return false; } m_pData[m_nIn] = data; m_nIn = (m_nIn + 1) % m_nBounds; m_nElements ++; /* notify waiter if any */ if(m_nEmptyWaiters) { FST_WAKE(&m_pEmptyCond); } FST_UNLOCK(&m_pMutex); return true;}bool FSTQueueManager::tryPop(void** data){ /* no more elements ever again */ if (m_bTerminate) { return false; } FST_LOCK(&m_pMutex); if(isEmpty()) { FST_UNLOCK(&m_pMutex); return false; } /* queue is terminated */ if(m_bTerminate) { FST_UNLOCK(&m_pMutex); return false; } *data = m_pData[m_nOut]; m_nElements --; m_nOut = (m_nOut + 1) % m_nBounds; /* notify waiter if any */ if (m_nFullWaiters) { FST_WAKE(&m_pFullCond); } FST_UNLOCK(&m_pMutex); return true;}bool FSTQueueManager::interruptAll(){ FST_LOCK(&m_pMutex); FST_WAKE(&m_pEmptyCond); FST_WAKE(&m_pFullCond); FST_UNLOCK(&m_pMutex); return true;}FSTQueueManager::~FSTQueueManager(void){ free(m_pData); FST_MUTEX_DESTROY(&m_pMutex); FST_COND_DESTROY(&m_pFullCond); FST_COND_DESTROY(&m_pEmptyCond);}bool FSTQueueManager::terminall(){ FST_LOCK(&m_pMutex); m_bTerminate = true; FST_UNLOCK(&m_pMutex); interruptAll();}
[解决办法]
既然有头有尾,当然可以遍历了
在中间弹出的话,需要移动后面的指针,不是很经济
[解决办法]
如果需要从中间操作,链表无疑是个优秀的结构,如果想用数组,可以尝试用数组实现链表。