1 回答

TA貢獻1828條經驗 獲得超4個贊
首先,互斥量這種線程相關的內容是平臺相關的,我假設你用的是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;
}
新建一個空的控制臺程序工程,向工程中加入這幾個文件,編譯之后可以直接運行。
第一個線程投入隊列100個元素,出隊50個元素,第二個線程同樣。最后主線程輸出隊列中最后的內容,然后清空。
隊列用鏈表實現,可以試想一下,如果線程同步沒有處理,指針操作時一定會引起崩潰
- 1 回答
- 0 關注
- 2094 瀏覽
添加回答
舉報