线程安全的队列写法

首先,互斥量这种线程相关的内容是平台相关的,我假设你用的是windows平台开发。
其次,说明一下我的开发环境,vs2008,控制台程序,空的工程。
最后给你贴代码,分文件来看。

===头文件QueueNode.h===
===你需要的节点数据可能不是整数,只要将typedef int QUEUEDATA这一句的int换成你想要的类型即可,但要注意,这个类型必须实现赋值操作符重载,相等比较操作符重载,以及复制构造函数===

#ifndef _QUEUE_NODE_H_
#define _QUEUE_NODE_H_

typedef int QUEUEDATA;

typedef struct node
{
	QUEUEDATA data;
	node* m_pNext;
}QUEUENODE;

#endif

===队列头文件Queue.h,有平台相关内容,请注意===
#ifndef _QUEUE_H_
#define _QUEUE_H_

#include "QueueNode.h"
#include <Windows.h>

class ThreadSafeQueue
{
public:
	ThreadSafeQueue();
	virtual ~ThreadSafeQueue();
	
	bool InitQueue();
	void EnQueue(const QUEUEDATA& data);
	void DeQueue();
	void Clear();
	const QUEUENODE* Find(const QUEUEDATA& data) const;
	void Print();

protected:
	HANDLE m_hMutex;
	QUEUENODE* m_pQueueHead;
};

#endif

===队列函数实现文件Queue.cpp===
#include "Queue.h"
#include <iostream>

ThreadSafeQueue::ThreadSafeQueue()
{
	m_pQueueHead = new QUEUENODE;
	m_pQueueHead->m_pNext = 0;
}

ThreadSafeQueue::~ThreadSafeQueue()
{
	Clear();
	delete m_pQueueHead;
	CloseHandle(m_hMutex);
}

bool ThreadSafeQueue::InitQueue()
{
	m_hMutex = CreateMutex(0, FALSE, 0);
	return (m_hMutex!=0);
}

void ThreadSafeQueue::EnQueue(const QUEUEDATA& data)
{
	WaitForSingleObject(m_hMutex, INFINITE);
	QUEUENODE* pNode = new QUEUENODE;
	pNode->data = data;
	pNode->m_pNext = 0;
	QUEUENODE* pTemp = m_pQueueHead;
	while (pTemp->m_pNext != 0)
	{
		pTemp = pTemp->m_pNext;
	}
	pTemp->m_pNext = pNode;
	ReleaseMutex(m_hMutex);
}

void ThreadSafeQueue::DeQueue()
{
	WaitForSingleObject(m_hMutex, INFINITE);
	QUEUENODE* pNode = m_pQueueHead->m_pNext;
	if (pNode != 0)
	{
		m_pQueueHead->m_pNext = pNode->m_pNext;
		delete pNode;
		pNode = 0;
	}
	ReleaseMutex(m_hMutex);
}

const QUEUENODE* ThreadSafeQueue::Find(const QUEUEDATA& data) const
{
	WaitForSingleObject(m_hMutex, INFINITE);
	QUEUENODE* pNode = m_pQueueHead->m_pNext;
	while (pNode != 0)
	{
		if (pNode->data == data)
		{
			break;
		}
		pNode = pNode->m_pNext;
	}
	return pNode;
	ReleaseMutex(m_hMutex);
}

void ThreadSafeQueue::Clear()
{
	WaitForSingleObject(m_hMutex, INFINITE);
	QUEUENODE* pNode = m_pQueueHead->m_pNext;
	QUEUENODE* pTemp = 0;
	while (pNode != 0)
	{
		pTemp = pNode->m_pNext;
		delete pNode;
		pNode = pTemp;
	}
	m_pQueueHead->m_pNext = 0;
	ReleaseMutex(m_hMutex);
}

void ThreadSafeQueue::Print()
{
	WaitForSingleObject(m_hMutex, INFINITE);
	QUEUENODE* pNode = m_pQueueHead->m_pNext;
	while (pNode != 0)
	{
		std::cout << pNode->data << "\t";
		pNode = pNode->m_pNext;
	}
	std::cout << std::endl;
	ReleaseMutex(m_hMutex);
}

===测试代码文件main.cpp,包含了测试用可执行程序,两个操作queue的线程,需要说明的是,我本来打算用WaitMultipleObjects函数来等待两个线程都结束,但是没搞清楚是什么问题没有卡住,不打算继续纠缠它了,所以让主线程Sleep了5秒钟===
#include "Queue.h"
#include <iostream>


DWORD WINAPI HandleQueue(void* pParam);
DWORD WINAPI HandleQueue2(void* pParam);

int main()
{
	ThreadSafeQueue queue;
	queue.InitQueue();
	HANDLE hThread[2] = {0};
	DWORD threadID = 0;
	hThread[0] = CreateThread(NULL, 0, HandleQueue, (void*)(&queue), NULL, &threadID);
	hThread[0] = CreateThread(NULL, 0, HandleQueue2, (void*)(&queue), NULL, &threadID);

	//WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
	Sleep(5000);
	queue.Print();
	queue.Clear();
	return 0;
}

DWORD WINAPI HandleQueue(void* pParam)
{
	ThreadSafeQueue* pQueue = reinterpret_cast<ThreadSafeQueue*>(pParam);
	for (int i = 0; i < 100; i++)
	{
		std::cout << "HandleQueue EnQueue" << std::endl;
		pQueue->EnQueue(i);
	}
	for (int i = 0; i < 50; i++)
	{
		std::cout << "HandleQueue DeQueue" << std::endl;
		pQueue->DeQueue();
	}
	return 0;
}

DWORD WINAPI HandleQueue2(void* pParam)
{
	ThreadSafeQueue* pQueue = reinterpret_cast<ThreadSafeQueue*>(pParam);
	for (int i = 0; i < 100; i++)
	{
		std::cout << "HandleQueue2 EnQueue" << std::endl;
		pQueue->EnQueue(i+100);
	}
	for (int i = 0; i < 50; i++)
	{
		std::cout << "HandleQueue2 DeQueue" << std::endl;
		pQueue->DeQueue();
	}
	return 0;
}


自己也写了一个,时间仓促,还未完成,是用双向链表做的

#include<iostream>
#include<windows.h>
using namespace std;

template<class T>
struct Node
{
	T value;
	Node<T>* next;
	Node<T>* previous;
};


template<class T>
class queue
{
public:
	queue();
	void enqueue(const Node<T>& node);
	void dequeue(Node<T>& node);
	void dequeue();
	Node<T>& getHead();
protected:
	HANDLE  mymutex;
	volatile Node<T>* head;
	volatile Node<T>* tail;
	volatile int nodeCount;
};

template<class T>
queue<T>::queue():nodeCount(0)
{
	Node<T>* node = new Node<T>;
	head = tail = node;
	node->next = NULL;
	node->previous = NULL;
	mymutex = CreateMutex(0, FALSE, 0);
}

template<class T>
void queue<T>::enqueue(const Node<T>& node)
{
	WaitForSingleObject(mymutex, INFINITE);
	
	Node<T>* pNode = new Node<T>(node);
	pNode->next = head->next;
	pNode->previous = head;
	head->next->previous = pNode;
	head->next = pNode;

	nodeCount++;

	ReleaseMutex(mymutex);
}

int main()
{
	return 0;
}


 

你可能感兴趣的:(线程安全的队列写法)