我正在尝试修复我的代码,我已经解决了僵局和互斥问题,但我不知道如何避免饥饿,因为在promela(PML)中没有监视器。 有人能帮我吗?提前致谢
bool forchetta0 = false,forchetta1 = false, forchetta2 = false,
forchetta3 = false, forchetta4 = false;
bool want0 = false, want1 = false, want2 = false, want3 = false, want4 = false;
active[5] proctype filosofo(){
printf("Filosofo %d -> sto pensando\n",_pid);
ciclo:
if
::true -> printf("Filosofo %d -> PENSO \n",_pid);
::true -> printf("Fisolofo %d -> voglio mangiare\n",_pid);
if
::_pid == 0 -> atomic{(!want4 &&!want1);want0 = true;}
forchetta0 = true; forchetta4 = true;
printf("Filosofo 0 -> STO MANGIANDO\n");
forchetta0 = false; forchetta4 = false;
want0 = false;
printf("Filosofo 0 -> HO FINITO DI MANGIARE\n");
::_pid == 1 -> atomic{(!want0 &&!want2);want1 = true;}
forchetta0 = true; forchetta1 = true;
printf("Filosofo 1 -> STO MANGIANDO\n");
forchetta0 = false; forchetta1 = false;
want1 = false;
printf("Filosofo 1 -> HO FINITO DI MANGIARE\n");
::_pid == 2 -> atomic{(!want1 &&!want3);want2 = true;}
forchetta1 = true; forchetta2 = true;
printf("Filosofo 2 -> STO MANGIANDO\n");
forchetta1 = false; forchetta2 = false;
want2 = false;
printf("Filosofo 2 -> HO FINITO DI MANGIARE\n");
::_pid == 3 -> atomic{(!want2&&!want4);want3= true;}
forchetta3 = true; forchetta2= true;
printf("Filosofo 3 -> STO MANGIANDO\n");
forchetta3 = false; forchetta2= false;
want3 = false;
printf("Filosofo 3 -> HO FINITO DI MANGIARE\n");
::_pid == 4 -> atomic{(!want0 &&!want3);want4= true;}
forchetta4 = true; forchetta3= true;
printf("Filosofo 4 -> STO MANGIANDO\n");
forchetta4 = false; forchetta3= false;
want4 = false;
printf("Filosofo 4 -> HO FINITO DI MANGIARE\n");
fi;
fi;
goto ciclo;
}
答案 0 :(得分:0)
你的代码中的缺陷是,如果他的一个邻居已经在尝试吃东西,每个哲学家都会避免吃东西,从某种意义上说,他们彼此表现得过于礼貌,因此它就是< strong>调度程序决定谁将会饿死。
有可能你在意识到如果每个哲学家是 ass 并且只是尽可能多地抓住那些叉子之后以这种方式设计代码,那么你可能会最终处于死锁状态。
正确的解决方案在于两个极端:你需要放松对每个哲学家的强烈承诺,以避免僵局,但不要太多,最终导致饥饿强>
避免死锁而不会引发饥饿的可行方法是引入利他主义哲学家的概念,即哲学家当它意识到由于另一个分叉已被使用而无法进食时,它会丢弃它所持有的分叉。
只有一个 利他主义哲学家就足以避免死锁,因此所有其他哲学家都可以继续贪婪并尝试尽可能多地抓取 。
但是,如果你在执行过程中从未改变谁 利他主义哲学家,那么你最终可能会让那个让自己饿死的家伙。因此,解决方案是无限地改变利他哲学家 。 公平战略是每当一位哲学家在死锁情况下无私地行动时,以循环方式改变它。通过这种方式,没有任何哲学家受到惩罚,你实际上可以验证哲学家在公平条件之下不会让调度程序为每个哲学家提供机会 >经常无限地执行。
为了帮助您在 Promela 中对此方法进行建模,我将向您提供以下 NuSMV 代码,它解决了同样的问题,取自 即使对于不了解 NuSMV 的人来说,代码应该是不言自明的。MODULE philosopher(ID, left_chopstick, right_chopstick, ALTRUIST, DEADLOCK)
VAR
state : {think, pickup, eat, putdown};
ASSIGN
init(state) := think;
next(state) := case
(DEADLOCK) & (ALTRUIST = ID): think;
(state = think): pickup;
(state = pickup) & (left_chopstick = 1) & (right_chopstick = 2): eat;
(state = eat): putdown;
(state = putdown) & !(left_chopstick = 1) & !(right_chopstick = 2): think;
TRUE : state;
esac;
next(left_chopstick) := case
(DEADLOCK) & (ALTRUIST = ID): 2;
(state = pickup) & (left_chopstick = 0): 1;
(state = putdown) & (left_chopstick = 1) & !(right_chopstick = 2): 0;
TRUE : left_chopstick;
esac;
next(right_chopstick) := case
(state = pickup) & (left_chopstick = 1) & (right_chopstick = 0): 2;
(state = putdown) & (right_chopstick = 2): 0;
TRUE : right_chopstick;
esac;
next(ALTRUIST) := case
(DEADLOCK) & (ALTRUIST = ID): (ALTRUIST mod 5) + 1;
TRUE : ALTRUIST;
esac;
FAIRNESS running