eMbedded Visual C++ 4.0eVCWindows MobileVisual C++ 7.0Visual Studio .NET 2003Windows XP移动应用中级开发Visual StudioWindowsC++
简单和多线程队列类






1.72/5 (6投票s)
2006年2月2日
2分钟阅读

55342

912
简单和多线程队列类
引言
本文描述了一个 C++ 队列类(简单和多线程安全版本)。队列是一种数据结构,它是一个先进先出 (FIFO) 列表。这意味着您可以推送元素,也可以“拉取”元素,并且每次拉取元素时,您都会拉取第一个推送的元素(先进先出)。队列非常适合缓冲数据或调度事件。队列的一个特征是它没有特定的容量。无论已经包含多少元素,都可以始终添加一个新元素。它也可以为空,此时删除元素将是不可能的,直到再次添加一个新元素为止。
类接口
由于队列类通常在多任务环境中使用的,我提供了简单和多线程安全的类的代码。
template <class Type> class Queue { public: Queue(); ~Queue(); BOOL Push(const Type & item); Type Pop(); BOOL IsEmpty(); void Reset(); };
template <class Type> class SafeQueue { public: Queue(); ~Queue(); BOOL Push(const Type & item); Type Pop(); BOOL IsEmpty(); void Reset(); };
使用代码
这个类有 3 个最重要的函数,它们实际上代表了 FIFO 逻辑。
BOOL Push(const Type & item);
Push()
函数将一个新元素添加到队列的开头。
Type Pop();
Pop()
函数从队列中检索(弹出)最后一个元素。如果队列中没有元素,它会抛出一个异常。为了避免异常,请使用 IsEmpty()
。
BOOL IsEmpty();
IsEmpty()
函数检查队列中是否有任何元素。
单线程示例
这是一个简短的示例,说明如何使用 Queue
类。它将 3 个字符串推送到一个列表,然后按添加的顺序逐个打印整个队列的元素。
#include "queue.h" #include "string" #include "stdio.h" using std::string; int main() { Queue<string> myQueue; myQueue.Push("Mr. "); myQueue.Push("Bill "); myQueue.Push("Gates "); while(!myQueue.IsEmpty()) { string s=myQueue.Pop(); puts(s.c_str()); } return 0; }
多线程示例
这是一个更有趣的示例,说明如何使用 SafeQueue
类。它有两个任务。第一个任务将 3 个字符串推送到一个列表,第二个任务按添加的顺序逐个打印元素。
#include "safequeue.h" #include "string" #include "stdio.h" #include "process.h" using std::string; SafeQueue<string> myQueue; volatile BOOL done=FALSE; void testThread(void *param) { myQueue.Push("Mr. "); ::Sleep(1000); myQueue.Push("Bill "); ::Sleep(1000); myQueue.Push("Gates "); ::Sleep(1000); done=TRUE; } int main() { _beginthread( testThread, 0, NULL ); while(!done) { if(!myQueue.IsEmpty()) { string s=myQueue.Pop(); puts(s.c_str()); } } return 0; }
“安全”队列
SafeQueue
类在内部使用一个临界区。对于每个函数调用,该区都会被锁定。这保证了不会有两个调用者同时推送/弹出数据。