哲学家就餐问题

来源:互联网 发布:帝国cms 栏目绑定信息 编辑:程序博客网 时间:2024/04/29 18:06

哲学家就餐问题。这是由计算机科学家Dijksta提出的经典死锁场景

问题描述:有5个哲学家,这些哲学家只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候必须使用餐具,而餐具是有限的。原版的故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。很显然把叉子换成筷子更合理,所以:一个哲学家需要两根筷子才能吃饭。

现在引入问题:这些哲学家很穷,只买的起5根筷子。他们做成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左边手和右边手的筷子。如果他们身边的任何一位正在使用筷子,那他只有等着。

假设哲学家的编号为A,B,C,D,E,筷子为1,2,3,4,5,哲学家和筷子围成一圈

序号 (哲学家) 左边右边

A 5 1

B 1 2

C 2 3

D 3 4

E 4 5

每个哲学家均为一个单独的线程,每个线程循环左以下动作:思考rand()% 10秒,然后先拿左手边的筷子再拿右边的筷子(筷子这种资源可以用mutex表示),有任何一边拿不到就一直等着,全拿到就吃饭rand()%10秒,然后放下筷子。

编写程序仿真哲学家就餐的场景:

philosopher A fetches chopsticks 5

philosopher B fetches chopsticks 1

...................

要想不产生死锁,只能用trylock,而不能用lock,否则有可能产生阻塞

代码(有点儿繁琐):

#include <stdio.h>#include <stdlib.h>#include <pthread.h>pthread_mutex_t one_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t two_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t three_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t four_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t five_mutex = PTHREAD_MUTEX_INITIALIZER;void think(void){usleep(rand() % 10);}void eat(void){usleep(rand() % 10);}void *thr_fn1(void *arg){while(1){think();//先思考一会儿printf("philosopher A is thinking\n");if(pthread_mutex_trylock(&five_mutex) == 0)//成功获得锁5{printf("Philosopher A fetches chopstick 5\n");if(pthread_mutex_trylock(&one_mutex) != 0)//如果没有获得锁1{pthread_mutex_unlock(&five_mutex);//解锁5printf("Philosopher A releases chopstick 5\n");continue;//接着尝试}//成功获得锁1printf("Philosopher A fetches chopstick 1\n");eat();//成功的话就eatprintf("philosopher A is eating\n");pthread_mutex_unlock(&five_mutex);pthread_mutex_unlock(&one_mutex);printf("Philosopher A releases chopstick 5 -- 1\n");}think();//不成功的话就think}}void *thr_fn2(void *arg){while(1){think();//不成功的话就sleepprintf("philosopher B is thinking\n");if(pthread_mutex_trylock(&one_mutex) == 0)//成功获得锁x{printf("Philosopher B fetches chopstick 1\n");if(pthread_mutex_trylock(&two_mutex) != 0)//如果没有获得锁y{pthread_mutex_unlock(&one_mutex);//解锁xprintf("Philosopher B releases chopstick 1\n");continue;//接着尝试}//成功获得锁yprintf("Philosopher B fetches chopstick 2\n");eat();printf("philosopher B is eating\n");pthread_mutex_unlock(&one_mutex);pthread_mutex_unlock(&two_mutex);            printf("Philosopher B releases chopstick 1 -- 2\n");}think();//不成功的话就sleep}}void *thr_fn3(void *arg){while(1){think();//不成功的话就sleepprintf("philosopher C is thinking\n");if(pthread_mutex_trylock(&two_mutex) == 0)//成功获得锁x{printf("Philosopher C fetches chopstick 2\n");if(pthread_mutex_trylock(&three_mutex) != 0)//如果没有获得锁y{pthread_mutex_unlock(&two_mutex);//解锁xprintf("Philosopher C releases chopstick 2\n");continue;//接着尝试}//成功获得锁yprintf("Philosopher C fetches chopstick 3\n");eat();printf("philosopher C is eating\n");pthread_mutex_unlock(&two_mutex);pthread_mutex_unlock(&three_mutex);printf("Philosopher C releases chopstick 2 -- 3\n");}think();//不成功的话就sleep}}void *thr_fn4(void *arg){while(1){        think();//不成功的话就sleep        printf("philosopher D is thinking\n");if(pthread_mutex_trylock(&three_mutex) == 0)//成功获得锁x{             printf("Philosopher D fetches chopstick 3\n");   if(pthread_mutex_trylock(&four_mutex) != 0)//如果没有获得锁y            {pthread_mutex_unlock(&three_mutex);//解锁xprintf("Philosopher D releases chopstick 3\n");continue;//接着尝试}//成功获得锁yprintf("Philosopher D fetches chopstick 4\n");eat();printf("philosopher D is eating\n");pthread_mutex_unlock(&three_mutex);pthread_mutex_unlock(&four_mutex);printf("Philosopher D releases chopstick 3 -- 4\n");}think();//不成功的话就sleep    }}void *thr_fn5(void *arg){while(1){think();//不成功的话就sleepprintf("philosopher E is thinking\n");if(pthread_mutex_trylock(&four_mutex) == 0)//成功获得锁x{printf("Philosopher E fetches chopstick 4\n");if(pthread_mutex_trylock(&five_mutex) != 0)//如果没有获得锁y{pthread_mutex_unlock(&four_mutex);//解锁xprintf("Philosopher E releases chopstick 4\n");                continue;//接着尝试}//成功获得锁yprintf("Philosopher E fetches chopstick 5\n");eat();printf("philosopher E is eating\n");pthread_mutex_unlock(&four_mutex);pthread_mutex_unlock(&five_mutex);            printf("Philosopher E releases chopstick 4 -- 5\n");}think();//不成功的话就sleep}}int main(void){pthread_t tid1,tid2,tid3,tid4,tid5;srand((unsigned int)time(NULL));pthread_create(&tid1,NULL,thr_fn1,NULL);pthread_create(&tid2,NULL,thr_fn2,NULL);pthread_create(&tid3,NULL,thr_fn3,NULL);     pthread_create(&tid4,NULL,thr_fn4,NULL);pthread_create(&tid5,NULL,thr_fn5,NULL);pthread_join(tid1,NULL);pthread_join(tid2,NULL);pthread_join(tid3,NULL);pthread_join(tid4,NULL);pthread_join(tid5,NULL);return 0;}



原创粉丝点击