当前位置:C++技术网 > 资讯 > 线程经典问题-生产者投放和消费者取出问题

线程经典问题-生产者投放和消费者取出问题

更新时间:2016-03-02 11:48:11浏览次数:1+次

秒杀多线程第十篇 生产者消费者问题》()一文中,详细的介绍了这个问题的来龙去脉以及分析。请你务必好好看看。

由于我喜欢用互斥器,因此这篇文章,我使用互斥器与信号量来解决消费者与生产者问题。对于信号量,互斥器的理解,请看《几段简单的文字教你秒懂事件,信号量,互斥器三大线程同步函数》我之前写代码的时候,单单就是用信号量来完成,觉得加了一个关键段费力,后来发现不行!至于为什么不行,其余秒杀多线程一文讲的很清楚了。你自己好好琢磨看看。好了,下面给出代码(对于输出颜色的代码,请看《利用SetConsoleTextAttribute函数设置控制台输出文字的颜色》):

#include "windows.h"
#include "stdio.h"

int ProductNum=8;
int BufferSize=4;
int Buffer[4];
int ProductPool,ConsumerPool;
HANDLE hSemaphoreEmpty,hSemaphoreFull;
HANDLE hMutex;

BOOL SetConsoleColor(WORD wAttributes)
{
	HANDLE hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
	if(hConsole==INVALID_HANDLE_VALUE)
	{
		return false;
	}
	return SetConsoleTextAttribute(hConsole,wAttributes);
}

DWORD WINAPI ProducterFunc(LPVOID pm)
{
	for(int i=1; i<=8; i++)
	{
		WaitForSingleObject(hSemaphoreEmpty,INFINITE);

		WaitForSingleObject(hMutex,INFINITE);

		Buffer[ProductPool]=i;
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		printf("生产者在缓冲池第%d个缓冲区中投放数据%d\n", ProductPool, Buffer[ProductPool]);  
		ProductPool=(ProductPool+1)%4;
		ReleaseSemaphore(hSemaphoreFull,1,NULL);
		ReleaseMutex(hMutex);
	}
	printf("生产者完成任务,线程结束运行\n");
	return 0;
}

DWORD WINAPI ConsumerFunc(LPVOID pm)
{
	while(1)
	{
		WaitForSingleObject(hSemaphoreFull,INFINITE);

		WaitForSingleObject(hMutex,INFINITE);
		SetConsoleColor(FOREGROUND_GREEN);
		printf("编号为%d的消费者从缓冲池中第%d个缓冲区取出数据%d\n", GetCurrentThreadId(), ConsumerPool, Buffer[ConsumerPool]);  

		if(Buffer[ConsumerPool]==8)
		{
			ReleaseSemaphore(hSemaphoreFull,1,NULL);
			ReleaseMutex(hMutex);
			break;
		}
		ConsumerPool=(ConsumerPool+1)%4;
		//Sleep(500);
		ReleaseSemaphore(hSemaphoreEmpty,1,NULL);
		ReleaseMutex(hMutex);
	}
	printf("编号为%d的消费者收到通知,线程结束运行\n", GetCurrentThreadId());
	return 0;
}

int main()
{
	hSemaphoreEmpty=CreateSemaphore(NULL,4,4,NULL);
	hSemaphoreFull=CreateSemaphore(NULL,0,4,NULL);
	hMutex=CreateMutex(NULL,FALSE,NULL);

	ProductPool=0;
	ConsumerPool=0;
	HANDLE handle[3];
	memset(Buffer,0,sizeof(Buffer));
	//生产者线程
	handle[0]=CreateThread(NULL,0,ProducterFunc,NULL,0,NULL);
	//消费者线程
	handle[1]=CreateThread(NULL,0,ConsumerFunc,NULL,0,NULL);
	handle[2]=CreateThread(NULL,0,ConsumerFunc,NULL,0,NULL);
	WaitForMultipleObjects(3,handle,TRUE,INFINITE);
	for(int i=0; i<3; i++)
	{
		CloseHandle(handle[i]);
	}

	CloseHandle(hSemaphoreEmpty);
	CloseHandle(hSemaphoreFull);
	CloseHandle(hMutex);

	system("pause");
	return 0;
}
运行图: