一个生产者,10个消费者,4个缓冲区
//有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,
//在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,
//显然生产者和消费者之间必须保持同步,
//即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次投放产品。
#include <iostream>
#include <Windows.h>
#include <process.h>
using namespace std;
//设置控制台输出颜色
BOOL SetConsoleColor(WORD wAttributes)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
return FALSE;
return SetConsoleTextAttribute(hConsole, wAttributes);
}
CRITICAL_SECTION ad;
HANDLE semaphore,eve,it;
const int n = 10;//消费者数目
const int buffersize=4;//缓冲区个数
//缓冲池
int buffer[buffersize];
int buffernum =0;
int buffernum2 =0;//
//消费者
unsigned int __stdcall customer(LPVOID pm)
{
WaitForSingleObject(semaphore,INFINITE);
EnterCriticalSection(&ad);
int i = *((int*)pm);
SetEvent(it);
SetConsoleColor(FOREGROUND_GREEN);
cout<<"消费者"<<GetCurrentThreadId()<<"在第"<<(i-1)%buffersize+1<<"缓冲池取出数据"<<buffer[(i-1)%buffersize]<<endl;
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
LeaveCriticalSection(&ad);
ReleaseSemaphore(eve,1,NULL);
return 0;
}
//生产者
unsigned int __stdcall produce(LPVOID pm)
{
for (auto i =0;i<n;i++)
{
WaitForSingleObject(eve,INFINITE);
EnterCriticalSection(&ad);
buffer[buffernum] =i;
cout<<"生产者"<<GetCurrentThreadId()<<"在第"<<buffernum+1<<"缓冲池生产数据"<<buffer[buffernum]<<endl;
buffernum=(i+1)%buffersize;
LeaveCriticalSection(&ad);
ReleaseSemaphore(semaphore,1,NULL);
}
return 0;
}
void main()
{
InitializeCriticalSection(&ad);
it = CreateEvent(NULL,FALSE,FALSE,NULL);
semaphore = CreateSemaphore(NULL,0,buffersize,NULL);//缓冲空的个数
eve =CreateSemaphore(NULL,buffersize,buffersize,NULL);//缓冲产品个数
HANDLE handle[n+1];
handle[0] = (HANDLE)_beginthreadex(NULL,0,produce,NULL,0,NULL);
for(int i=1;i<n+1;i++)
{
handle[i] = (HANDLE)_beginthreadex(NULL,0,customer,&i,0,NULL);
WaitForSingleObject(it,INFINITE);
}
WaitForMultipleObjects(n,handle,true,INFINITE);
system("pause");
for (auto j =0;j <2;j++)
{
CloseHandle(handle[j]);
}
CloseHandle(semaphore);
CloseHandle(eve);
CloseHandle(it);
DeleteCriticalSection(&ad);
}