多线程之生产者消费者

6 篇文章 1 订阅
3 篇文章 0 订阅

看了别人写的多线程例子,自己也写了一个,贴上了防止以后忘记

此例子有2个生产者,4个消费者,4个缓冲区,共生产12件商品

#include "stdafx.h"
#include <stdio.h>  
#include <process.h>  
#include <windows.h>
HANDLE g_hEventBufferFull,g_hEventBufferEmpty;
CRITICAL_SECTION g_cs;
const int Product_Num=12;//12件商品
const int Buffer_Size=4;//4个缓冲区
int Buffer[Buffer_Size];
int j=0;//生产者正在用的缓冲区
int k=0;//消费者正在用的缓冲区
int i=1;//已生成商品数量,同时代表每个商品的内容
bool gBuffer=false;
unsigned int __stdcall ProductFun(PVOID pM)
{
	while(i<=Product_Num)
	{
		WaitForSingleObject(g_hEventBufferFull,INFINITE);
		EnterCriticalSection(&g_cs);
		if(Product_Num<i)//这里生产者缓冲区一直会多执行一次到13,大概是
			              //因为上一个线程i++到13.而第二个线程已经在循环内,所以为13
						  //g_hEventBufferFull在消费者正常结束下是大于0的,所以出现数据
						  //为13的情况,所以特加此判断
		{
			LeaveCriticalSection(&g_cs);
			ReleaseSemaphore(g_hEventBufferEmpty,1,NULL);
			break;
		}
		Buffer[j]=i;
		printf("编号为%d的生产者在缓冲区%d中投放数据%d\n",GetCurrentThreadId(),j,Buffer[j]);
			j=(j+1)%Buffer_Size;
			i++;
			Sleep(50);//Sleep是为了给其他的线程腾出一些时间,充分体现出乱序的特点。否则CPU的执行速度很快,
			           //很可能在其他线程刚刚开启,当前线程已经执行完了,造成线程有序执行的假象。
			LeaveCriticalSection(&g_cs);
			ReleaseSemaphore(g_hEventBufferEmpty,1,NULL); 
	}
	printf("生产者%d完成任务,线程结束运行\n",GetCurrentThreadId()); 
	return 0; 

}
unsigned int __stdcall ConsumerFun(PVOID pM)
{
	while(true)
	{
	    WaitForSingleObject(g_hEventBufferEmpty,INFINITE);
		EnterCriticalSection(&g_cs);
		if(true==gBuffer)
		{
			break;
		}
		printf("    编号为%d的Consumer在缓冲区%d中取走数据%d\n",GetCurrentThreadId(),k,Buffer[k]);
		if(Buffer[k]==Product_Num)//这里的本意是为了结束另一个线程,不造成死锁,但造成了消费重复,所以在
			                      //上边加了一个判断
		{
			LeaveCriticalSection(&g_cs); 
				ReleaseSemaphore(g_hEventBufferEmpty,1,NULL);
				gBuffer=true;
				break;
		}
		k=(k+1)%Buffer_Size;
		Sleep(50);
		LeaveCriticalSection(&g_cs); 
		ReleaseSemaphore(g_hEventBufferFull,1,NULL);
	}
	 printf("    编号为%d的消费者收到通知,线程结束运行\n", GetCurrentThreadId());  
	 return 0; 
}
int main()
{
	printf("生产者消费者问题by ShallWe\n");
	InitializeCriticalSection(&g_cs);
	g_hEventBufferFull=CreateSemaphore(NULL,4,4,NULL);
	g_hEventBufferEmpty=CreateSemaphore(NULL,0,4,NULL);
	HANDLE Thread[4];
	memset(Buffer,0,sizeof(Buffer));
	Thread[0]=(HANDLE)_beginthreadex(NULL,0,ProductFun,NULL,0,NULL);
	Thread[1]=(HANDLE)_beginthreadex(NULL,0,ProductFun,NULL,0,NULL);
	Thread[2]=(HANDLE)_beginthreadex(NULL,0,ConsumerFun,NULL,0,NULL);
	Thread[3]=(HANDLE)_beginthreadex(NULL,0,ConsumerFun,NULL,0,NULL);
	WaitForMultipleObjects(4, Thread, TRUE, INFINITE);
	    for (int i = 0; i < 4; i++)  
        CloseHandle(Thread[i]);  
  
    //销毁信号量和关键段  
    CloseHandle(g_hEventBufferFull);  
    CloseHandle(g_hEventBufferEmpty);  
    DeleteCriticalSection(&g_cs);  
	system("pause");
	return 0;

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值