?? 多線程模擬哲學家就餐.txt
字號:
操作系統課程設計實驗報告之多線程模擬哲學家就餐問題
多線程模擬哲學家就餐問題
-----Amoon 2005/09/23
1)問題描述
學操作系統的進程同步都要涉及到三個經典問題:生產者-消費者問題、讀者-寫者問題和哲學家就餐問題。下面來介紹一下哲學家就餐問題: 哲學家就餐問題中,一組哲學家圍坐在一個圓桌旁,每個哲學家的左邊都只有一只筷子(當然他的右邊也有一只筷子,但是這是他右邊哲學家的左邊的筷子),他們吃完了就思考,思考了一會就會餓,餓了就想吃,然而,為了吃飯,他們必須獲得左邊和右邊的筷子。當每個哲學家只拿有一只筷子的時候,會坐者等另一只筷子,在每個哲學家都只拿一個筷子的時候,就會發生死鎖。
2)關于源碼的一點說明:
應用CRITICAL_SECTION 變量解決數據共享問題。
3)vc6下源碼如下( 經作者在vc6下測試通過運行 ):
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <time.h>
#include <fstream>
#include <string>
#include <iostream>
#include <assert.h>
#include <time.h>
using namespace std;
ofstream out("out.txt");
BOOL b[6];//共享數據,用于表示 5 雙筷子的使用情況,FALSE代表被占用
CRITICAL_SECTION cs;
class philosopher
{
private:
int m_num; //編號
int m_index; //標示裝態,0-------waiting 1-----eating 2-----thinking
BOOL m_lhand; //true -----筷子空閑,false----筷子被占用
BOOL m_rhand;
public:
philosopher(int num=0) { m_num=num; m_index=2; m_lhand=TRUE; m_rhand = FALSE ;}
int GetNum() const { return m_num; }
int GetStatus() const { return m_index ; }
void ChangeStatus() ;
};
void philosopher::ChangeStatus()
{
EnterCriticalSection (&cs) ;
if(m_index==1) //eating----->thinking
{
assert(!b[m_num]);
b[m_num]=TRUE;
if( m_num==1)
{
assert(!b[5]);
b[5]= TRUE;
}
else
b[m_num-1]=TRUE;
m_index=2; // change to thinking
srand(time(NULL)*10000);
Sleep(rand()%10);
}
else if( m_index==2) //thinking
{
m_index=0; //change to waiting
}
else if( m_index==0) // waiting
{
if(m_num==1)
{
if(b[1]&&b[5])
{
b[1]=FALSE;
b[5]=FALSE;
m_index=1;
srand(time(NULL)*10000);
Sleep(rand()%10);
}
}
else
{
if(b[m_num]&&b[m_num-1])
{
b[m_num]= FALSE;
b[m_num-1]= FALSE;
m_index=1;
srand(time(NULL)*10000);
Sleep(rand()%10);
}
}
}
LeaveCriticalSection (&cs) ;
}
//ust to out the philosopher info
string PrintStatus(philosopher *pPh)
{
pPh->ChangeStatus();
int i=pPh->GetStatus();
string str;
if(i==0)
str="Waiting";
else if(i==1)
str="eating";
else str="thinking";
return str;
}
void ThreadFunc1(PVOID param)
{
while(1)
{
philosopher *pPh;
pPh=( philosopher *) param;
pPh->ChangeStatus();
}
}
void ThreadFunc2(PVOID param)
{
while(1)
{
philosopher *pPh;
pPh=( philosopher *) param;
pPh->ChangeStatus();
}
}
void ThreadFunc3(PVOID param)
{
while(1)
{
philosopher *pPh;
pPh=( philosopher *) param;
pPh->ChangeStatus();
}
}
void ThreadFunc4(PVOID param)
{
while(1)
{
philosopher *pPh;
pPh=( philosopher *) param;
pPh->ChangeStatus();
}
}
void ThreadFunc5(PVOID param)
{
while(1)
{
philosopher *pPh;
pPh=( philosopher *) param;
pPh->ChangeStatus();
}
}
int main()
{
for(int j=1;j<=5;j++) b[j]=TRUE;
out<<b[1]<<b[2]<<b[3]<<b[4]<<b[5];
philosopher ph1(1),ph2(2),ph3(3),ph4(4),ph5(5);
InitializeCriticalSection (&cs) ;
_beginthread(ThreadFunc1,0,&ph1);
_beginthread(ThreadFunc2,0,&ph2);
_beginthread(ThreadFunc3,0,&ph3);
_beginthread(ThreadFunc4,0,&ph4);
_beginthread(ThreadFunc5,0,&ph5);
cout<<"press ctrl+C to exit";
while(1)
{
out<<endl<<b[1]<<b[2]<<b[3]<<b[4]<<b[5]<<endl; // use to test
out<<"The status at :"<<clock()<<" ms "<<endl;
out<<"哲學家"<<ph1.GetNum() <<"所處狀態:"<<ph1.GetNum()<<"--"<<PrintStatus(&ph1)<<endl;
out<<"哲學家"<<ph2.GetNum() <<"所處狀態:"<<ph2.GetNum()<<"--"<<PrintStatus(&ph2)<<endl;
out<<"哲學家"<<ph3.GetNum() <<"所處狀態:"<<ph3.GetNum()<<"--"<<PrintStatus(&ph3)<<endl;
out<<"哲學家"<<ph4.GetNum() <<"所處狀態:"<<ph4.GetNum()<<"--"<<PrintStatus(&ph4)<<endl;
out<<"哲學家"<<ph5.GetNum() <<"所處狀態:"<<ph5.GetNum()<<"--"<<PrintStatus(&ph5)<<endl;
Sleep(20);
}
DeleteCriticalSection (&cs) ;
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -