15,473
社区成员




#pragma once
#include <windows.h>
typedef struct node
{
int iId;
char name[32];
}NODE, *PNODE;
class CQueue
{
CQueue(const CQueue& rhs);
public:
CQueue(int nCapity = 10);
~CQueue();
void Lock(bool bLock = TRUE);
bool Insert(PNODE pNode);
void Pop(PNODE pNode);
int iCapity;
int iHead;
int iTail;
int iCount;
CRITICAL_SECTION cs;
HGLOBAL gBuffer;
HANDLE hEvent;
HANDLE hPop, hInsert;
BYTE threadID;
};
#include "queue.h"
#include <stdio.h>
#include <windows.h>
CQueue::CQueue(int nCapity /* = 1000 */)
{
InitializeCriticalSection(&cs);
iCapity = nCapity;
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hPop = CreateEvent(NULL, FALSE, FALSE, NULL);
hInsert = CreateEvent(NULL, FALSE, FALSE, NULL);
gBuffer = GlobalAlloc(GPTR, nCapity * sizeof(NODE));
threadID = -1;
if (NULL == gBuffer)
{
;
}
iHead = iTail = iCount = 0;
}
void CQueue::Lock(bool bLock /* = TRUE */)
{
if (bLock)
{
EnterCriticalSection(&cs);
}
else
{
LeaveCriticalSection(&cs);
}
}
CQueue::~CQueue()
{
DeleteCriticalSection(&cs);
CloseHandle(hEvent);
CloseHandle(hPop);
CloseHandle(hInsert);
if (NULL != gBuffer)
{
GlobalFree(gBuffer);
}
}
bool CQueue::Insert(PNODE pNode)
{
Lock(TRUE);
pNode->iId++;
if (iCount >= iCapity)
{
Lock(false);
WaitForSingleObject(hInsert, INFINITE);
Lock(true);
}
if (iCount==0)
{
iHead = 0;
}
int threadId = GetCurrentThreadId();
printf("IN[%d]:iId=%d\n", threadId, pNode->iId);
memcpy((LPVOID)((DWORD)gBuffer + iTail*sizeof(NODE)), pNode, sizeof(NODE));
iTail = (iTail+1) % iCapity;
iCount++;
SetEvent(hPop);
Lock(FALSE);
return true;
}
void CQueue::Pop(PNODE pNode)
{
if(NULL == pNode)
return;
Lock(TRUE);
if (iCount==0)
{
Lock(FALSE);
WaitForSingleObject(hPop, INFINITE);
Lock(TRUE);
}
LPVOID des = (LPVOID)((DWORD)gBuffer + iHead*sizeof(NODE));
memcpy((LPVOID)pNode, des, sizeof(NODE));
iHead = (iHead+1) % iCapity;
iCount--;
if (pNode != NULL)
{
int threadId = GetCurrentThreadId();
printf("OUT[%d]:iId=%d\n", threadId, pNode->iId);
}
SetEvent(hInsert);
Lock(FALSE);
}
#include <iostream>
#include <conio.h>
#include <windows.h>
#include "queue.h"
using namespace std;
#define MAX_GET 10
#define MAX_INSERT 10
static NODE m_node;
static CQueue queue;
DWORD WINAPI Insert(LPVOID lParam)
{
CQueue* pQueue = (CQueue*)lParam;
if (pQueue == NULL)
{
return 0;
}
// while (WAIT_TIMEOUT == WaitForSingleObject(pQueue->hEvent, 0))
{
pQueue->Insert(&m_node);
Sleep(5000);
}
return 0;
}
DWORD WINAPI Pop(LPVOID lParam)
{
CQueue* pQueue = (CQueue*)lParam;
if (pQueue == NULL)
{
return 0;
}
NODE PopValue;
// while (WAIT_TIMEOUT == WaitForSingleObject(pQueue->hEvent, 0))
{
pQueue->Pop(&PopValue);
Sleep(5000);
}
return 0;
}
HANDLE threadGet[MAX_GET];
HANDLE threadInsert[MAX_INSERT];
int main(int argc, char* argv)
{
for (int num = 0; num < MAX_GET; num++)
{
threadGet[num] = CreateThread(NULL, 0, Insert, (LPVOID)&queue, 0, NULL);
CloseHandle(threadGet[num]);
}
for(num = 0; num < MAX_INSERT; num++)
{
threadInsert[num] = CreateThread(NULL, 0, Pop, (LPVOID)&queue, 0, NULL);
CloseHandle(threadInsert[num]);
}
cout<<"press any key to exit."<<endl;
while (!kbhit())
{
}
SetEvent(queue.hEvent);
WaitForMultipleObjects(MAX_GET, threadGet, true, INFINITE);
WaitForMultipleObjects(MAX_INSERT, threadInsert, true, INFINITE);
return 0;
}
4
if(iCount==0)
{
iHead=0;
}
你仔细看看这里,iCount==0的时候你把iHead置0,在Pop线程中执行了iCount--;所以每当Pop一次之后再Insert的时候你都把iHead置0,程序可不就是你上面那个样子啦
for (int num = 0; num < MAX_GET; num++)
{
threadGet[num] = CreateThread(NULL, 0, Insert, (LPVOID)&queue, 0, NULL);
threadInsert[num] = CreateThread(NULL, 0, Pop, (LPVOID)&queue, 0, NULL);
CloseHandle(threadInsert[num]);
CloseHandle(threadGet[num]);
}