|
多线程模拟哲学家就餐问题 -----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; }
|