多核多執行緒中小和尚老和尚取水喝水問題
阿新 • • 發佈:2019-02-16
最近學習多核多執行緒技術,最後的考試題目是和尚的問題。題目具體如下:
某寺廟有小和尚、老和尚若干。廟內有一水缸、由小和尚提水入缸,供老和尚引用。水缸可容納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; }