哲学家进餐问题

    先直接上代码

 1 #define N  5            /* 哲学家数目 */
 2 #define LEFT  (i+N-1)%N       /* i的左邻编号 */
 3 #define RIGHT  (i+ 1)%N       /* i的右邻编号 */
 4 #define THINKING  0        /* 哲学家在思考 */
 5 #define HUNGRY  1          /*哲学家试图拿起叉子 */
 6 #define EATING  2          /* 哲学家进餐 */
 7 typedef int semaphore;      /*信号量 */
 8 int state[N];            /*记录每位哲学家状态 */
 9 semaphore mutex = 1 ;       /*临界区的互斥 */
10 semaphore s[N];          /* 每位哲学家一个信号量 */
11
12 void philosopher(int i)      /* i: 哲学家编号, 从0到N-1 */
13 {
14     while (TRUE) {          /* 无限循环 */
15         think();          /* 哲学家思考 */
16         take_ forks(i);      /* 测试叉子是否可用 */
17         eat();           /* 哲学家进餐 */
18         put_ forks(i);       /* 将叉子放回到桌子上 */
19   }
20 }
21
22 void take_forks(int i)      
23 {
24     down(&mutex);          /* 进入临界区 */
25     state[i] = HUNGRY;       /* 记录哲学家i处于饥饿状态 */
26     test(i);             /* 尝试获取两把叉子 */
27     up(&mutex);           /* 退出临界区 */
28     down(&s[i]);          /* 如果得不到需要的叉子则阻塞 */
29 }
30
31 void put_forks(i)         
32 {
33     down(&mutex);         /* 进入临界区 */
34     state[i] =THINKING;      /* 哲学家进餐完毕 */
35     test(LEFT);           /* 测试左邻是否可以吃 */
36     test( RIGHT);         /* 测试右邻是否可以吃 */
37     up(&mutex);           /* 离开临界区 */
38 }
39
40 void test(i)          41 {
42     if (state[i] ==HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
43         state[i] = EATING;
44         up(&s[i]);
45     }
46 }

    一位哲学家只有在两个邻居都没有进餐时才允许进入到进餐状态!

时间: 2024-12-26 05:50:35

哲学家进餐问题的相关文章

【操作系统】经典的同步问题(生产者消费者问题, 哲学家进餐问题, 读写问题)

用专业术语来说, 进程是程序的一次动态执行.说简单点, 就是进程是系统中的某个任务.操作系统中有多个任务需要执行, 那么怎样执行才能使它们同步呢? 即如何让任务并发执行互不影响呢? 这就引出了进程同步中的经典问题: 生产者消费者问题, 哲学家进餐问题, 读写问题 生产者-消费者问题 有一群生产者进程在生产产品, 并将这些产品提供给消费者进程取消费. 为使生产者进程与消费者进程能并发进行, 在两者间设置了一个具有n个缓冲区的缓冲池, 生产者进程将其所生产的产品翻入缓冲区中, 消费者进程可从一个缓冲

利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题

首先说一下什么是哲学家进餐问题,这是操作系统课程中一个经典的同步问题, 问题如下:如上图,有6个哲学家和6根筷子(那个蓝色部分表示哲学家,那个紫色长条部分表示筷子),他们分别被编了0~5的号!如果某个哲学家想要进餐的话,必须同时拿起左手和右手边的两根筷子才能进餐!哲学家进餐完毕之后,就放下手中拿起的两根筷子!这样其他哲学家就能拿这些筷子进餐了!注意这个哲学家的个数必须是偶数个! OK,这样就可能存在一个死锁问题,比如0号哲学家拿了0号筷子,1号哲学家拿了1号筷子!如此往复,最终的结果就是每个哲学

哲学家进餐

问题描述 一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆一根筷子,桌子的中间是一碗米饭,如图2-10所示.哲学家们倾注毕生精力用于思考和进餐,哲学家在思考时,并不影响他人.只有当哲学家饥饿的时候,才试图拿起左. 右两根筷子(一根一根地拿起).如果筷子已在他人手上,则需等待.饥饿的哲学家只有同时拿到了两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考. 问题分析 1) 关系分析.5名哲学家与左右邻居对其中间筷子的访问是互斥关系. 2) 整理思路.显然这里有五个进程.本题的关键是如何让一个哲

【ThinkingInJava】63、哲学家进餐问题

/** * 书本:<Thinking In Java> * 功能:哲学家进餐问题 * 作为哲学家,他们很穷,所以他们只能买五根筷子.他们围坐在桌子周围,每人之间放一根筷子.当一个哲学家要就餐的时候了,这个哲学家必须同时得到左边 * 和右边的筷子.如果一个哲学家左边或右边的筷子已经有人在使用筷子了,那么这个哲学家就必须等待,直至可以得到必须的筷子 * 文件:Chopstick.java * 时间:2015年5月9日15:08:21 * 作者:cutter_point */ package Les

java笔记--超级类Object多线程的应用+哲学家进餐算法内部类与多线程结合

关于Object类中的线程方法: Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notifyAll(),wait(),这几个方法都是用来控制线程的运行状态的. 方法列表如下: notify() : 唤醒在此对象监视器上等待的单个线程 notifyAll() : 唤醒在此对象监视器上等待的所有线程 wait() : 在其他线程时调用此对象的notify()或者notifyAll()方法前,

【操作系统总结】哲学家进餐问题

哲学家进餐问题 问题:有五个哲学家公用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,平时一个哲学家进行思考,饿的时候便取用左右做靠近他的筷子,只有他拿到两只筷子时才能进餐,进餐完毕继续思考 利用记录型信号量解决问题 semaphore chopstick[5] = {1, 1, 1, 1, 1};//每一个筷子一个信号量 do { wait(chopstick[i]);//首先这个筷子能不能拿到,否则自我阻塞 wait(chopstick[(i + 1) % 5]);//再判断

Java总结(十)—实现Runnable接口创建线程,线程安全同步,死锁(哲学家进餐问题),读写锁

一.通过实现Runnable接口创建线程 定义实现Runnable接口的类 (1)Runnable接口中只有一个方法public void run();用来定义线程运行体: class MyRun implements Runnable(){ public void run(){ 线程执行的具体代码 } } (2)创建线程的实例的时候将这个类的实例作为参数传递到线程实例内部.然后再启动: Thread thread=new Thread(new MyRun()); Thread.start();

经典进程的同步问题之——哲学家进餐

哲学家进餐问题描述 由Dijkstra提出并解决哲学家进餐问题(The Dinning Philosophers Problem)是经典的同步问题.该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在桌子上有五个碗和五只筷子,他们的生活方式是交替的进行思考和进餐.平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有他拿到两只筷子时才能进餐,进餐完毕继续进行思考. 1 利用记录型信号量解决哲学家进餐问题 经过分析可知,圆桌上的筷子是临界资源,在一段时间内只允许一位哲学

信号量解决哲学家进餐问题

参考线程同步之信号量(sem_init,sem_post,sem_wait) - 郑志强Aloha - 博客园 以及<操作系统概念>第七版 第六章 项目:生产者-消费者问题 题目描述: 哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,n哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,n平时哲学家进行思考,饥饿时便试图取其左.右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,n进餐完毕,放下筷子又继续思考. 如图. 编号都为0-4.哲学家0-3左