模拟有五个哲学家的哲学家进餐问题。 问题描述:哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。要求是:每一个哲学家只有在拿到位于他左右的筷子后,才能够就餐;哲学家只能先拿左边的筷子,再去拿右边的筷子,而不能同时去抓他两边的筷子,也不能从其他哲学家手中抢夺筷子;哲学家每次就餐后必须放下他手中的两把筷子后恢复思考,不能强抓住餐具不放。 原理B:仅当哲学家的左右筷子都可用时,才允许他拿

#include <windows.h>

#include <iostream>

#include <process.h>

#include <cstdlib>

#include <ctime>

#include <string>

using namespace std;

//线程函数

unsigned int __stdcall philosopher( void * );

bool think( int );

bool eat( int );

void wait( int );

void print();

int count = 0; //用于记录输出的次数

string phil_state[ 5 ]; //哲学家状态(思考、等待、吃饭)

bool stick[ 5 ]; //筷子的状态(有没有人正在使用)

//临界区结构变量

CRITICAL_SECTION crout; //保证输出时不会竞争

CRITICAL_SECTION chopsticks[ 5 ]; //定义五个临界变量,代表五根筷子

//线程函数

unsigned int __stdcall philosopher( void *k )

{

int n = ( ( int * ) k )[ 0 ];

srand( time( NULL ) );

while( true )

{

think( n );

eat( n );

}

return n;

}

//思考

bool think( int k )

{

if( phil_state[ k ] == "waiting" )

return false;

else

{

phil_state[ k ] = "thinking";

print();

return true;

}

}

//

bool eat( int k )

{

//只有同时获得两根筷子才能吃饭,否则进入等待状态

if( stick[ k ] == true && stick[ (k + 1 ) % 5 ] == true )//若果哲学家两边的筷子值为true则可以获得筷子

{

EnterCriticalSection( chopsticks + k );//获得左边的筷子

stick[ k ] = false;

EnterCriticalSection( chopsticks + ( k + 1 ) % 5 );//获得右边的筷子

stick[ (k + 1 ) % 5 ] = false;//获得筷子后把获得的筷子状态变为false避免被其他人争夺筷子

phil_state[ k ] = "eating";//把哲学家自己状态变为eating

print();

//释放临界区

stick[ (k + 1 ) % 5 ] = true;

stick[ k ] = true;

phil_state[ k ] = "thinking";//哲学家放下筷子状态变为thinking

LeaveCriticalSection( chopsticks + ( k + 1 ) % 5 );//放下右边的筷子

LeaveCriticalSection( chopsticks + k );//放下左边的筷子

return true;

}

else

{

wait( k );

return false;

}

}

//等待

void wait(int k)

{

phil_state[ k ] = "waiting";

print();

}

//输出函数

void print()

{

EnterCriticalSection( &crout );

count ++;

cout << "The " << count << "th time : " << endl;

for( int i = 0; i < 5; i ++ )

cout << "Philosoper " << i + 1 << " is " << phil_state[ i ] << endl;

cout << endl;

Sleep( 3000 );

LeaveCriticalSection( &crout );

}

int main()

{

void * hthread[ 5 ];

int i;

unsigned int threadid[ 5 ];

int arg[ 5 ];

unsigned long retval;

//初始化哲学家和筷子的状态

for(  i = 0; i < 5; i ++ )

{

phil_state[ i ] = "thinking";

stick[ i ] = true;

 

}

//初始化临界变量

InitializeCriticalSection( &crout );

for(i=0;i<5;i++)

{

InitializeCriticalSection( chopsticks + i );

}

//创建五个哲学家线程

for( i = 0; i < 5;i ++ )

{

arg[ i ] = i;

hthread[i]=(void *)_beginthreadex(NULL,0,philosopher,(void *)(arg + i),0,threadid+i);

if( ( int ) hthread[ i ] == -1 ) //如果线程创建失败返回-1

{

cerr << "Create thread error :" << i <<endl;

cerr << "Error code : "<< GetLastError() <<endl;

}

}

 

retval = WaitForMultipleObjects( 5, hthread, true, INFINITE ); //等待多个线程

 

if( retval == WAIT_FAILED )

 

{

cerr << "Wait error,error code: "<< GetLastError() << endl;

}

for( i = 0; i < 5; i ++ )

{

if( CloseHandle( hthread[ i ] ) == false )

{

cerr << "Close thread error: " << i <<endl;

cerr << "Error code: "<< GetLastError() <<endl;

}

}

return 0;

posted @ 2017-10-25 22:36  can丶  阅读(1736)  评论(0编辑  收藏  举报