// ThreadTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <map>
#include <queue>
CRITICAL_SECTION g_cs; // mutex
HANDLE g_hEmptyBufferSemaphore;
HANDLE g_hFullBufferSemaphore;
#define INVALID -1
#define PRODUCER 5
#define CUSTOMER 5
#define NUM_COUNT 8
#define BUFF_SIZE 4
static std::queue<int> bufferQueue;
static std::map< DWORD,int > countMap;
bool ProducerFinish = false;
//设置控制台输出颜色
BOOL SetConsoleColor(WORD wAttributes)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
return FALSE;
return SetConsoleTextAttribute(hConsole, wAttributes);
}
DWORD WINAPI ProducerFunc(LPVOID param)
{
while(true)
{
WaitForSingleObject( g_hEmptyBufferSemaphore, INFINITE);
EnterCriticalSection(&g_cs);
DWORD threadId = GetCurrentThreadId();
if(countMap.find(threadId) == countMap.end())
countMap[threadId] = 0;
int productID = ++countMap[threadId];
bufferQueue.push( productID);
printf("生产者%d , 生产%d\n", threadId, productID);
if( productID == NUM_COUNT )
{
SetConsoleColor(FOREGROUND_RED);
printf("生产者%d生产完毕\n",GetCurrentThreadId());
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(g_hFullBufferSemaphore, 1, NULL);
break;
}
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(g_hFullBufferSemaphore, 1, NULL);
}
return NULL;
}
DWORD WINAPI CustomerFunc(LPVOID param)
{
while (true)
{
WaitForSingleObject( g_hFullBufferSemaphore, INFINITE);
EnterCriticalSection(&g_cs);
int buffer = -1;
if(!bufferQueue.empty())
{
buffer = bufferQueue.front();
bufferQueue.pop();
}
if(buffer != INVALID )
printf("消费者%d ,消费%d\n", GetCurrentThreadId() , buffer);
if( bufferQueue.empty() && ProducerFinish)
{
printf("消费者%d 结束\n",GetCurrentThreadId());
LeaveCriticalSection(&g_cs);
// 通知其他消费者可以结束了
ReleaseSemaphore( g_hFullBufferSemaphore, 1, NULL);
break;
}
LeaveCriticalSection(&g_cs);
ReleaseSemaphore( g_hEmptyBufferSemaphore, 1, NULL);
}
return NULL;
}
int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection(&g_cs);
g_hEmptyBufferSemaphore = CreateSemaphore( NULL, 4, 4, NULL);
g_hFullBufferSemaphore = CreateSemaphore( NULL, 0, 4, NULL);
HANDLE producerThreads[PRODUCER];
HANDLE customerThreads[CUSTOMER];
// producer
for (int i = 0; i < PRODUCER; ++i)
{
producerThreads[i] = CreateThread( NULL, 0, ProducerFunc, NULL, NULL, NULL);
}
// customers
for (int i = 0; i < CUSTOMER; ++i)
customerThreads[i] = CreateThread( NULL, 0, CustomerFunc, NULL, NULL, NULL);
WaitForMultipleObjects( PRODUCER, producerThreads, TRUE, INFINITE);
ProducerFinish = true;
WaitForMultipleObjects( CUSTOMER, customerThreads, TRUE, INFINITE);
for (int i = 0; i < PRODUCER; ++i)
CloseHandle(producerThreads[i]);
for (int i = 0; i < CUSTOMER; ++i)
CloseHandle(customerThreads[i]);
CloseHandle(g_hEmptyBufferSemaphore);
CloseHandle(g_hFullBufferSemaphore);
DeleteCriticalSection(&g_cs);
countMap.clear();
return 0;
}