65.9K
CodeProject 正在变化。 阅读更多。
Home

简单和多线程队列类

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.72/5 (6投票s)

2006年2月2日

2分钟阅读

viewsIcon

55342

downloadIcon

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 类在内部使用一个临界区。对于每个函数调用,该区都会被锁定。这保证了不会有两个调用者同时推送/弹出数据。

© . All rights reserved.