生产者消费者模型是经典的线程同步问题,该模型如下:生产者生产产品,并将产品放在一个缓冲区中,供消费者消费。显然消费者和生产者之间必须保持同步,即不允许消费者在一个空的缓冲区中取产品,也不允许生产者向一个满的缓冲区中投放产品。
同步所要解决的问题,即对缓冲区的访问,可以用关键段和信号量来解决。
假设现在需要解决的问题如下:生产者每次生产一个数据,生产五次,然后通知消费者一次消费这五次数据
<pre name="code" class="cpp">#include <process.h>
#include <windows.h>
int ret[5] = {1,2,3,4,5};
int num = 0;//表示生产者生产次数
int data_buffer[25] = {0};
//float *cur = data_buffer;
CRITICAL_SECTION data_cs;
HANDLE databufNotEmpty, databufNotFull;
void inition()
{
InitializeCriticalSection(&data_cs); //初始化信号量;
databufNotEmpty = CreateSemaphore(NULL, 0, 1, NULL);//表示databufNotEmpty的初始值为0
databufNotFull = CreateSemaphore(NULL, 5, 5, NULL);//表示databufNotFull的初始值为5,表示生产者可以生产5次
//将data_buffer内存初始化为0;
memset(data_buffer,0,sizeof(data_buffer));//sizeof(data_buffer)=sizeof(float)*25;
}
unsigned int _stdcall producer(LPVOID lp) //生产者
{
while (1)
{
//缓冲区非满;P()
WaitForSingleObject(databufNotFull, INFINITE);
EnterCriticalSection(&data_cs);
memcpy(data_buffer+num, ret, sizeof(ret));//内存复制,将ret内存拷贝到cur;
num = num + 5;
printf("******producer*****\n");
LeaveCriticalSection(&data_cs);
if (num == 25) //等待缓冲区满
{
ReleaseSemaphore(databufNotEmpty, 1, NULL);
}
}
return 0;
}
unsigned int _stdcall consumer(LPVOID lp)
{
while (1)
{
//等待缓冲区非空
WaitForSingleObject(databufNotEmpty, INFINITE);
EnterCriticalSection(&data_cs);
memset(data_buffer, 0, sizeof(data_buffer));
printf("******consumer******\n");
num = 0;
LeaveCriticalSection(&data_cs);
ReleaseSemaphore(databufNotFull, 5, NULL);
}
return 0;
}
int main()
{
inition();
HANDLE h_Thread[2];
h_Thread[0] = (HANDLE)_beginthreadex(NULL, 0, producer, NULL, 0, NULL);
h_Thread[1] = (HANDLE)_beginthreadex(NULL, 0, consumer, NULL, 0, NULL);
WaitForMultipleObjects(2,h_Thread,true,INFINITE);
CloseHandle(h_Thread[0]);
CloseHandle(h_Thread[1]);
getchar();
return 0;
}
结果如下: