OSQueue用法
来源:互联网 发布:windows xp 64位原版 编辑:程序博客网 时间:2024/06/05 16:42
#ifndef _OSQUEUE_H_#define _OSQUEUE_H_#include "MyAssert.h"#include "OSHeaders.h"#include "OSMutex.h"#include "OSCond.h"#include "OSThread.h"#define OSQUEUETESTING 0class OSQueue;class OSQueueElem { public: OSQueueElem(void* enclosingObject = NULL) : fNext(NULL), fPrev(NULL), fQueue(NULL), fEnclosingObject(enclosingObject) {} virtual ~OSQueueElem() { Assert(fQueue == NULL); } Bool16 IsMember(const OSQueue& queue) { return (&queue == fQueue); } Bool16 IsMemberOfAnyQueue() { return fQueue != NULL; } void* GetEnclosingObject() { return fEnclosingObject; } void SetEnclosingObject(void* obj) { fEnclosingObject = obj; } OSQueueElem* Next() { return fNext; } OSQueueElem* Prev() { return fPrev; } OSQueue* InQueue() { return fQueue; } inline void Remove(); private: OSQueueElem* fNext; OSQueueElem* fPrev;//每个元素内部通过队列指针能够判断出该元素是否是该队列中的元素,同时也可以通过该元素直接从队列中将自己删除 OSQueue * fQueue; void* fEnclosingObject; friend class OSQueue;};class OSQueue { public: OSQueue(); ~OSQueue() {}//进队 void EnQueue(OSQueueElem* object);//出队 OSQueueElem* DeQueue();//获取队头元素 OSQueueElem* GetHead() { if (fLength > 0) return fSentinel.fPrev; return NULL; }//获取队尾元素 OSQueueElem* GetTail() { if (fLength > 0) return fSentinel.fNext; return NULL; }//获取队列长度 UInt32 GetLength() { return fLength; } //删除某个元素 void Remove(OSQueueElem* object);#if OSQUEUETESTING static Bool16 Test();#endif protected://双向链表头节点,不存储任何元素,使插入删除元素方便 OSQueueElem fSentinel; UInt32 fLength;};class OSQueueIter{ public://默认让fCurrentElemP指向队列头 OSQueueIter(OSQueue* inQueue) : fQueueP(inQueue), fCurrentElemP(inQueue->GetHead()) {}//让fCurrentElemP指向startElemP,startElemP必须是队列中的元素,如果不是则让fCurrentElemP指向空 OSQueueIter(OSQueue* inQueue, OSQueueElem* startElemP ) : fQueueP(inQueue) { if ( startElemP ) { Assert( startElemP->IsMember(*inQueue ) ); fCurrentElemP = startElemP; } else fCurrentElemP = NULL; } ~OSQueueIter() {} //重置当前元素位置,使其为队列头 void Reset() { fCurrentElemP = fQueueP->GetHead(); } //获取当前元素 OSQueueElem* GetCurrent() { return fCurrentElemP; }//fCurrentElemP指向下一个元素 void Next(); //队列空了 Bool16 IsDone() { return fCurrentElemP == NULL; } private://队列指针 OSQueue* fQueueP;//队列指向的当前元素 OSQueueElem* fCurrentElemP;};class OSQueue_Blocking{ public: OSQueue_Blocking() {} ~OSQueue_Blocking() {} //出队列,如果队列没有元素,则阻塞,直到调用EnQueue发出信号后,才解除阻塞 OSQueueElem* DeQueueBlocking(OSThread* inCurThread, SInt32 inTimeoutInMilSecs);//出队列,不会阻塞,如果队列没有元素,则直接返回空 OSQueueElem* DeQueue();//will not block//每次入队列的时候,都会调用Signal发出信号 void EnQueue(OSQueueElem* obj); OSCond* GetCond() { return &fCond; } OSQueue* GetQueue() { return &fQueue; } private: OSCond fCond; OSMutex fMutex; OSQueue fQueue;};void OSQueueElem::Remove(){ if (fQueue != NULL) fQueue->Remove(this);}#endif //_OSQUEUE_H_
#include "OSQueue.h"OSQueue::OSQueue() : fLength(0){ fSentinel.fNext = &fSentinel; fSentinel.fPrev = &fSentinel;}void OSQueue::EnQueue(OSQueueElem* elem){ Assert(elem != NULL); if (elem->fQueue == this) return; Assert(elem->fQueue == NULL); elem->fNext = fSentinel.fNext; elem->fPrev = &fSentinel; elem->fQueue = this; fSentinel.fNext->fPrev = elem; fSentinel.fNext = elem; fLength++;}OSQueueElem* OSQueue::DeQueue(){ if (fLength > 0) { OSQueueElem* elem = fSentinel.fPrev; Assert(fSentinel.fPrev != &fSentinel); elem->fPrev->fNext = &fSentinel; fSentinel.fPrev = elem->fPrev; elem->fQueue = NULL; fLength--; return elem; } else return NULL;}void OSQueue::Remove(OSQueueElem* elem){ Assert(elem != NULL); Assert(elem != &fSentinel); if (elem->fQueue == this) { elem->fNext->fPrev = elem->fPrev; elem->fPrev->fNext = elem->fNext; elem->fQueue = NULL; fLength--; }}#if OSQUEUETESTINGBool16 OSQueue::Test(){ OSQueue theVictim; void *x = (void*)1; OSQueueElem theElem1(x); x = (void*)2; OSQueueElem theElem2(x); x = (void*)3; OSQueueElem theElem3(x); if (theVictim.GetHead() != NULL) return false; if (theVictim.GetTail() != NULL) return false; theVictim.EnQueue(&theElem1); if (theVictim.GetHead() != &theElem1) return false; if (theVictim.GetTail() != &theElem1) return false; OSQueueElem* theElem = theVictim.DeQueue(); if (theElem != &theElem1) return false; if (theVictim.GetHead() != NULL) return false; if (theVictim.GetTail() != NULL) return false; theVictim.EnQueue(&theElem1); theVictim.EnQueue(&theElem2); if (theVictim.GetHead() != &theElem1) return false; if (theVictim.GetTail() != &theElem2) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem1) return false; if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem2) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem2) return false; theVictim.EnQueue(&theElem1); theVictim.EnQueue(&theElem2); theVictim.EnQueue(&theElem3); if (theVictim.GetHead() != &theElem1) return false; if (theVictim.GetTail() != &theElem3) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem1) return false; if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem3) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem2) return false; if (theVictim.GetHead() != &theElem3) return false; if (theVictim.GetTail() != &theElem3) return false; theElem = theVictim.DeQueue(); if (theElem != &theElem3) return false; theVictim.EnQueue(&theElem1); theVictim.EnQueue(&theElem2); theVictim.EnQueue(&theElem3); OSQueueIter theIterVictim(&theVictim); if (theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != &theElem3) return false; theIterVictim.Next(); if (theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != &theElem2) return false; theIterVictim.Next(); if (theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != &theElem1) return false; theIterVictim.Next(); if (!theIterVictim.IsDone()) return false; if (theIterVictim.GetCurrent() != NULL) return false; theVictim.Remove(&theElem1); if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem3) return false; theVictim.Remove(&theElem1); if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem3) return false; theVictim.Remove(&theElem3); if (theVictim.GetHead() != &theElem2) return false; if (theVictim.GetTail() != &theElem2) return false; return true;} #endifvoid OSQueueIter::Next(){ if (fCurrentElemP == fQueueP->GetTail()) fCurrentElemP = NULL; else fCurrentElemP = fCurrentElemP->Prev();}OSQueueElem* OSQueue_Blocking::DeQueueBlocking(OSThread* inCurThread, SInt32 inTimeoutInMilSecs){ OSMutexLocker theLocker(&fMutex);#ifdef __Win32_ if (fQueue.GetLength() == 0) {fCond.Wait(&fMutex, inTimeoutInMilSecs);return NULL; }#else if (fQueue.GetLength() == 0) fCond.Wait(&fMutex, inTimeoutInMilSecs);#endif OSQueueElem* retval = fQueue.DeQueue(); return retval;}OSQueueElem* OSQueue_Blocking::DeQueue(){ OSMutexLocker theLocker(&fMutex); OSQueueElem* retval = fQueue.DeQueue(); return retval;}void OSQueue_Blocking::EnQueue(OSQueueElem* obj){ { OSMutexLocker theLocker(&fMutex); fQueue.EnQueue(obj); } fCond.Signal();}
0 0
- OSQueue用法
- DSS Source Code Analyse (25) - OSQueue
- 用法
- ,, 用法
- 用法
- 用法
- #用法
- ??用法
- !!用法
- CustDialog用法 SimpleAdapter 用法
- hibernate_Restrictions用法 hibernate_Restrictions用法
- extern用法+assert用法
- getParameterValues用法
- rpm用法
- Log4j用法
- NameSpace用法
- sp_executesql 用法
- ShellExecute用法
- angularJs 简单实例
- Google C++ Style Guide学习心得
- 开源日志系统比较:scribe、chukwa、kafka、flume
- super oj p528
- MMX汇编指令优化
- OSQueue用法
- 关于类中定义的函数与windows API定义的函数名相同的链接问题
- 【VS开发】【C++开发】正确使用auto_ptr智能指针
- select下拉框的使用方案
- ACM基本输入输出
- 数字证书原理(HTTPS&SSL)
- 网站高并发的处理措施
- 如何在线预览office文档
- ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk