*利用管程机制实现。

  • 原理:不是对每只筷子设置信号量,而是对每个哲学家设置信号量。
  • test()函数有以下作用:
  • a.如果当前处理的哲学家处于饥饿状态并且两侧的哲学家不在吃饭状态
  • 则当前哲学家通过test函数试图进入吃饭状态
  • b.如果通过test进入吃饭状态不成功,那么当前的哲学家就在该信号量阻塞等待
  • 直到其他哲学家进程通过test将该哲学家的状态设置为eating
  • c.当一个哲学家进程调用put_forks放下筷子时,会通过test测试它的邻居,如果
  • 邻居处于饥饿状态,且该邻居的邻居不在吃饭状态,则该邻居进入吃饭状态
  • 由上,该算法不会出现思索。但是该算法会出现某个哲学家始终无法吃饭的情况
  • 即当该哲学家的左右两个哲学家交替处在吃饭的状态的时候,则该哲学家始终无法
  • 进入吃饭状态。
  • 但是该算法可以实现对于任意多位哲学家的情况都能获得最大的并行度,因此具有重要的意义。*/

管程模板如下:(看一个大神写的模板)

#define N 5
#define left (i-1+N)%N
#define right (i+1)%N
typedef enum{thinking,hungry,eating} phil_state;
monitor dp{
phil_state state[N];
semaphore mutex = 1;
semaphore s[N];
void test(int i){
if(state[i] == hungry && state[left(i)] != eating && state[left(i)] != eating){
state[i] = eating;
V(s[i]);
}
}
void get_forks(int i){
P(mutex);
state[i] = hungry;
test(i);
V(mutex);
P(s[i]);
}
void put_forks(int i){
P(mutex);
state[i] = thinking;
test(left(i));
test(right(i));
V(mutex);
}
}
哲学家进程如下:
void philovopher(int process){
while(true){
think();
get_forks();
eat();
put_forks(process);
}
}

作者:keneyr
来源:CSDN
原文:https://blog.csdn/keneyr/article/details/50435647
版权声明:本文为博主原创文章,转载请附上博文链接!

更多推荐

哲学家就餐问题之管程