1. 程式人生 > >生產者消費者問題

生產者消費者問題

creates 控制 ios mut tin 代碼 pty ont har

C代碼:

#include <windows.h>
#include <iostream>
const unsigned short SIZE_OF_BUFFER = 2; //緩沖區長度
unsigned short ProductID = 0; //產品號
unsigned short ConsumeID = 0; //將被消耗的產品號
unsigned short in = 0; //產品進緩沖區時的緩沖區下標
unsigned short out = 0; //產品出緩沖區時的緩沖區下標
int buffer[SIZE_OF_BUFFER]; //緩沖區是個循環隊列操作系統課程設計指導書
bool p_ccontinue = true; //控制程序結束
HANDLE Mutex; //用於線程間的相互排斥
HANDLE FullSemaphore; //當緩沖區滿時迫使生產者等待
HANDLE EmptySemaphore; //當緩沖區空時迫使消費者等待
DWORD WINAPI Producer(LPVOID); //生產者線程
DWORD WINAPI Consumer(LPVOID); //消費者線程
int main()
{
	//創建各個相互排斥信號
	//註意,相互排斥信號量和同步信號量的定義方法不同,相互排斥信號量調用的是 CreateMutex 函數。
	//調用的是 CreateSemaphore 函數。函數的返回值都是句柄。
	Mutex = CreateMutex(NULL,FALSE,NULL);
	EmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER,SIZE_OF_BUFFER,NULL);
	//將上句做例如以下改動,看看結果會如何
	//EmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);
	FullSemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);
	//調整以下的數值,能夠發現。當生產者個數多於消費者個數時,
	//生產速度快,生產者常常等待消費者;反之,消費者常常等待
	const unsigned short PRODUCERS_COUNT = 3; //生產者的個數
	const unsigned short CONSUMERS_COUNT = 1; //消費者的個數
	//總的線程數
	const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;
	HANDLE hThreads[THREADS_COUNT]; //各線程的 handle
	DWORD producerID[PRODUCERS_COUNT]; //生產者線程的標識符
	DWORD consumerID[CONSUMERS_COUNT]; //消費者線程的標識符
	//創建生產者線程
	for (int i=0;i<PRODUCERS_COUNT;++i){
		hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);
		if (hThreads[i]==NULL) return -1;
	}
	//創建消費者線程
	for (i=0;i<CONSUMERS_COUNT;++i){
		hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]);
		if (hThreads[i]==NULL) return -1;
	}
	while(p_ccontinue){
		if(getchar()){ //按回車後終止程序執行操作系統課程設計指導書
			p_ccontinue = false;
		}
	}
	return 0;
}
//生產一個產品。簡單模擬了一下,僅輸出新產品的 ID 號
void Produce()
{
	std::cout << std::endl<< "Producing " << ++ProductID << " ... ";
	std::cout << "Succeed" << std::endl;
}
//把新生產的產品放入緩沖區
void Append()
{
	std::cerr << "Appending a product ... ";
	buffer[in] = ProductID;
	in = (in+1)%SIZE_OF_BUFFER;
	std::cerr << "Succeed" << std::endl;
	//輸出緩沖區當前的狀態
	for (int i=0;i<SIZE_OF_BUFFER;++i){
		std::cout << i <<": " << buffer[i];
		if (i==in) std::cout << " <-- 生產";
		if (i==out) std::cout << " <-- 消費";
		std::cout << std::endl;
	}
}
//從緩沖區中取出一個產品
void Take()
{
	std::cerr << "Taking a product ... ";
	ConsumeID = buffer[out];
	buffer[out] = 0;
	out = (out+1)%SIZE_OF_BUFFER;
	std::cerr << "Succeed" << std::endl;
	//輸出緩沖區當前的狀態
	for (int i=0;i<SIZE_OF_BUFFER;++i){
		std::cout << i <<": " << buffer[i];
		if (i==in) std::cout << " <-- 生產";
		if (i==out) std::cout << " <-- 消費";
		std::cout << std::endl;
	}
}
//消耗一個產品
void Consume()
{
	std::cout << "Consuming " << ConsumeID << " ... ";
	std::cout << "Succeed" << std::endl;
}
//生產者
DWORD WINAPI Producer(LPVOID lpPara)
{
	while(p_ccontinue){
		WaitForSingleObject(EmptySemaphore,INFINITE); //p(empty);
		WaitForSingleObject(Mutex,INFINITE); //p(mutex);
		Produce();
		Append();
		Sleep(1500);
		ReleaseMutex(Mutex); //V(mutex);
		ReleaseSemaphore(FullSemaphore,1,NULL); //V(full);
	}
	return 0;
}
//消費者
DWORD WINAPI Consumer(LPVOID lpPara)
{
	while(p_ccontinue){
		WaitForSingleObject(FullSemaphore,INFINITE); //P(full);
		WaitForSingleObject(Mutex,INFINITE); //P(mutex);
		Take();
		Consume();
		Sleep(1500);
		ReleaseMutex(Mutex); //V(mutex);
		ReleaseSemaphore(EmptySemaphore,1,NULL); //V(empty);
	}
	return 0;
}

生產者消費者問題