1. 程式人生 > >多核多執行緒中小和尚老和尚取水喝水問題

多核多執行緒中小和尚老和尚取水喝水問題

最近學習多核多執行緒技術,最後的考試題目是和尚的問題。題目具體如下:

某寺廟有小和尚、老和尚若干。廟內有一水缸、由小和尚提水入缸,供老和尚引用。水缸可容納10桶水,每次入水、取水都為1桶,且不可同時進行。水取自同一井中,水井口很小,每次只能容納一隻水桶取水。設水桶個數為3個。試寫出小和尚和老和尚的函式,假設有5個小和尚同時提水入缸,5個老和尚同時取水喝(每隔一定時間取水一次),編寫程式使他們能同步進行。

努力一下,最後終於寫出來了。程式碼如下

#include"windows.h"
#include<iostream>
using namespace std;

HANDLE sjing=CreateSemaphore(NULL,1,1,"sem1");//井的訊號量
HANDLE stong=CreateSemaphore(NULL,2,2,"sem2");//小和尚用的水桶的訊號量
HANDLE stong1=CreateSemaphore(NULL,1,1,"sem3");//老和尚用的水桶的訊號量
HANDLE sgang=CreateSemaphore(NULL,1,1,"sem4");//水缸的訊號量
HANDLE full=CreateSemaphore(NULL,0,10,"sem5");//缸中可以取的水的桶數
HANDLE empty=CreateSemaphore(NULL,10,10,"sem6");//缸中可以容納的水桶數
int count=0;
CRITICAL_SECTION cs;

DWORD WINAPI youngFunc(LPVOID pArg)
{
	int i=(int)pArg;
	while(1)
	{
		
		WaitForSingleObject(stong,INFINITE);//小和尚先取得水桶
		printf("%d號小和尚拿到了桶\n",i);
		WaitForSingleObject(sjing,INFINITE);//小和尚先取得水井
		printf("%d號小和尚打上了水\n",i);
		ReleaseSemaphore(sjing,1,NULL);//小和尚釋放水井
		
		Sleep(1000);
		WaitForSingleObject(empty,INFINITE);//判斷水缸是否已滿
		WaitForSingleObject(sgang,INFINITE);//取得水缸的使用
		printf("\t\t%d號小和尚向缸中倒水\n",i);
		EnterCriticalSection(&cs);
		count++;
		printf("\t\t缸中有%d桶\n",count);
		LeaveCriticalSection(&cs);
		ReleaseSemaphore(sgang,1,NULL);//釋放水缸
		ReleaseSemaphore(stong,1,NULL);//釋放水桶
		printf("%d號小和尚放下了桶\n",i);
		ReleaseSemaphore(full,1,NULL);//水缸中可使用水數量加1
	
	
	}
	return NULL;
}

DWORD WINAPI oldFunc(LPVOID pArg)
{
	int i=(int)pArg;
	while(1)
	{
		Sleep(4000);
		WaitForSingleObject(full,INFINITE);//判斷水缸是否有水
		WaitForSingleObject(stong1,INFINITE);//取得水桶
		printf("\t\t\t\t\t%d號老和尚拿到了桶\n",i);
		WaitForSingleObject(sgang,INFINITE);//取得水缸的使用
		printf("\t\t\t\t\t%d號老和尚喝到了水\n",i);
		EnterCriticalSection(&cs);
		count--;
		printf("\t\t缸中有%d桶\n",count);
		LeaveCriticalSection(&cs);
		ReleaseSemaphore(sgang,1,NULL);//釋放水缸
		ReleaseSemaphore(stong1,1,NULL);//釋放水桶
		printf("\t\t\t\t\t\t\t%d號老和尚放下了桶\n",i);
		ReleaseSemaphore(empty,1,NULL);//水缸中可放水數量加1
	}
	return NULL;
}

int main()
{   
	
	HANDLE young[5];
	HANDLE old[5];
	InitializeCriticalSection(&cs);
	
	for(int i=0;i<5;i++)
	{
		young[i]=CreateThread(NULL,0,youngFunc,LPVOID(i),NULL,NULL);
		old[i]=CreateThread(NULL,0,oldFunc,LPVOID(i),NULL,NULL);
	}
	
	HANDLE p[2];
	p[0]=young;
	p[1]=old;
	WaitForMultipleObjects(5,p,TRUE,INFINITE);
	getchar();

	return 0;
}
題目中給了三個木桶,如果對木桶不進行區分,會產生死鎖。當小和尚佔了三個水桶,並且水缸中的水已經滿了,這時候老和尚等待水桶取水,但是沒有水桶了,老和尚只能等待。小和尚佔著水桶,等待老和尚喝水,但是老和尚沒有水桶沒法喝,小和尚也只能一直等待。所以產生了死鎖,所以才將水桶分開解決死鎖。