哲学家就餐问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*inux进程的实现:哲学家就餐问题在 linux 上的程序实现
设有5个哲学家,共享一张放油把椅子的桌子,每人分得一吧椅子.但是桌子上总共只有5支筷子,在每个人两边分开各放一支.哲学家只有在肚子饥饿时才试图分两次从两边拾起筷子就餐.
就餐条件是:
1)哲学家想吃饭时,先提出吃饭的要求;
2)提出吃饭要求,并拿到2支筷子后,方可吃饭;
3)如果筷子已被他人获得,则必须等待该人吃完饭之后才能获取该筷子;
4)任一哲学家在自己未拿到2支筷子吃饭之前,决不放下手中的筷子;
5)刚开始就餐时,只允许2个哲学家请求吃饭.
试问:
1)描述一个保证不会出现两个邻座同时要求吃饭的算法;
2)描述一个既没有两邻座同时吃饭,又没有人饿死的算法;
3)在什么情况下,5个哲学家全都吃不上饭?
哲学家进餐问题是典型的同步问题.它是由Dijkstra提出并解决的.该问题是描述有五个哲学家,他们的生活方式是交替地进行思考和进餐.哲学家们共用一张圆桌,分别坐在周围的五张椅子上.在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左右岁靠近他的筷子,只有在他拿到两支筷子时才能进餐.进餐完毕,放下筷子继续思考.
*/
#include
#include
#include
#include
#include
#include
//#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 { 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); } }