C++進階—>互斥量:Event控制:多線程實現生產者-消費者例子

     一個典型的生產者-消費者問題,它們公用的資源是SharedBuffer,當Buffer中有數據且未滿時,兩個線程都可以運行,當Buffer爲 空時,Consumer就要等待,直到Buffer不爲空,這裏就是用event來實現的;同樣,當Buffer爲滿時,Producer就要等待。

     開發環境:VS2012,win32控制檯程序

#include "stdafx.h"
#include <iostream>
#include <windows.h>

using namespace std;

#define BUFSIZE 5
int SharedBuffer[BUFSIZE];
int head,tail;
int cont;

HANDLE hMutex;
HANDLE hNotFullEvent, hNotEmptyEvent;

void BB_Producer()
{
	int i;
	for (i=20; i>=0; i--) {
		while(1) {
			WaitForSingleObject(hMutex,INFINITE);
			if (cont == BUFSIZE) { // 緩衝區滿
				ReleaseMutex(hMutex);
				// 等待直到緩衝區非滿
				WaitForSingleObject(hNotFullEvent,INFINITE);
				continue;
			}
			// 得到互斥鎖且緩衝區非滿,跳出while循環
			break;
		}
		// 得到互斥鎖且緩衝區非滿,開始產生新數據
		cout << "Produce: " << i << endl;
		SharedBuffer[tail] = i;
		tail = (tail+1) % BUFSIZE;
		cont++;
		ReleaseMutex(hMutex); // 結束臨界區
		PulseEvent(hNotEmptyEvent); // 喚醒消費者線程
	}
}
void BB_Consumer()
{
	int result;
	while (1) {
		WaitForSingleObject(hMutex,INFINITE);
		if (cont == 0) { // 沒有可以處理的數據
			ReleaseMutex(hMutex); // 釋放互斥鎖且等待
			// 等待直到緩衝區非空
			WaitForSingleObject(hNotEmptyEvent,INFINITE);
		}
		else if (SharedBuffer[head] == 0) {
			cout << "Consumed 0: end of data" << endl;
			ReleaseMutex(hMutex); // 結束臨界區
			ExitThread(0);
		}
		else { // 獲得互斥鎖且緩衝區有數據,開始處理
			result = SharedBuffer[head];
			cout << "Consumed: " << result << endl;
			head = (head+1) % BUFSIZE;
			cont--;
			ReleaseMutex(hMutex); // 結束臨界區
			PulseEvent(hNotFullEvent); // 喚醒生產者線程
		}
	}
}
int main()
{
	HANDLE hThreadVector[2];
	DWORD ThreadID;
	cont = 0;
	head = 0;
	tail = 0;
	hMutex = CreateMutex(NULL,FALSE,NULL);
	hNotFullEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	hNotEmptyEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	hThreadVector[0] = CreateThread (NULL, 0,
		(LPTHREAD_START_ROUTINE) BB_Producer,
		NULL, 0, (LPDWORD)&ThreadID);
	hThreadVector[1] = CreateThread (NULL, 0,
		(LPTHREAD_START_ROUTINE) BB_Consumer,
		NULL, 0, (LPDWORD)&ThreadID);
	WaitForMultipleObjects(2,hThreadVector,TRUE,INFINITE);

	system("pause");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章