/*inux进程的实现:哲学家就餐问题在 linux 上的程序实现
设有5个哲学家,共享一张放油把椅子的桌子,每人分得一吧椅子.但是桌子上总共只有5支筷子,在每个人两边分开各放一支.哲学家只有在肚子饥饿时才试图分两次从两边拾起筷子就餐.
就餐条件是:
1)哲学家想吃饭时,先提出吃饭的要求;
2)提出吃饭要求,并拿到2支筷子后,方可吃饭;
3)如果筷子已被他人获得,则必须等待该人吃完饭之后才能获取该筷子;
4)任一哲学家在自己未拿到2支筷子吃饭之前,决不放下手中的筷子;
5)刚开始就餐时,只允许2个哲学家请求吃饭.
试问:
1)描述一个保证不会出现两个邻座同时要求吃饭的算法;
2)描述一个既没有两邻座同时吃饭,又没有人饿死的算法;
3)在什么情况下,5个哲学家全都吃不上饭?
哲学家进餐问题是典型的同步问题.它是由Dijkstra提出并解决的.该问题是描述有五个哲学家,他们的生活方式是交替地进行思考和进餐.哲学家们共用一张圆桌,分别坐在周围的五张椅子上.在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左右岁靠近他的筷子,只有在他拿到两支筷子时才能进餐.进餐完毕,放下筷子继续思考.
*/
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
//#include "RasUtil.h"
using namespace std;
const unsigned int PHILOSOPHER_NUM=5;
const char THINKING=1;
const char HUNGRY=2;
const char DINING=3;
sem_t semph[PHILOSOPHER_NUM]; // each fork has a semaphore
pthread_mutex_t mutex; // Mutex for printing
void* philosopherProc(void* param);
int main(int argc, char* argv[])
int i;
srand(getpid());
pthread_t philosopherThread[PHILOSOPHER_NUM]; //定义线程数组
int phId[PHILOSOPHER_NUM];
pthread_mutex_init(&mutex, NULL);
for (i=0; i<PHILOSOPHER_NUM; i++)
{
phId[i] = i;
sem_init(&semph[i], 0, 1); //对每只筷子信号量进行初始化为当前进程的局部信号量
pthread_create(&philosopherThread[i], NULL, philosopherProc, (void*)(&phId[i])); //以philosopherProc为原型创建PHILOSOPHER_NUM个线程
usleep(5000);
}
sleep(30);
return 0;
}
void* philosopherProc(void* param)
{
int myid;
char stateStr[128];
char mystate;
int ret;
unsigned int leftFork;
unsigned int rightFork;
myid = *((int*)(param));
cout << "philosopher " << myid << " begin......" << endl;
usleep(1000000); //把进程挂起一段时间,单位是微秒(百万分之一秒);
// initial state is THINKING
mystate = THINKING;
leftFork = (myid) % PHILOSOPHER_NUM;
rightFork = (myid + 1) % PHILOSOPHER_NUM;
while (true)
{
switch(mystate)
{
case THINKING:
// changing my state
mystate = HUNGRY;
strcpy(stateStr, "HUNGRY");
break;
case HUNGRY:
strcpy(stateStr, "HUNGRY");
// first test the left fork ...
ret = sem_trywait(&semph[leftFork]);
if (ret == 0)
{
// left fork is ok, take it up ,then test the right fork ...
ret = sem_trywait(&semph[rightFork]);
if (ret == 0)
{
// right fork is also ok ! changing my state
mystate = DINING;
strcpy(stateStr, "DINING");
}
else
{
// right fork is being used by others, so I must put down the left fork. sem_post(&semph[leftFork]);
}
}
break;
case DINING:
// put down both the left and right fork
sem_post(&semph[leftFork]);
sem_post(&semph[rightFork]);
// changing my state
mystate = THINKING;
strcpy(stateStr, "THINKING");
break;
}
// print my state
pthread_mutex_lock(&mutex);
cout << "philosopher " << myid << " is : " << stateStr << endl;
pthread_mutex_unlock(&mutex);
// sleep a random time : between 1 - 5 s
int sleepTime;
sleepTime = 1 + (int)(5.0*rand()/(RAND_MAX+1.0));
usleep(sleepTime*100000);
}
}。