操作系统中经典的死锁的问题

哲学家就餐问题是操作系统中关于进程同步与互斥的经典问题,也是涉及死锁的关键问题,下面我们以解决经典的进程同步问题——哲学家就餐问题来考查如何利用资源有序分配法防止死锁。

有5个哲学家以思考、用餐交替进行的方式生活,他们坐在一张圆桌边,桌子上有5个盘子和5只筷子。如图5-13所示。 当一个哲学家思考时,他与邻座的哲学家没有任何联系。当一个哲学家感觉到饿了,他就试图拿 起他左右两边的筷子用餐。如果他的邻座已经拿到筷子,则他可能只拿到一只甚至一只筷子也拿不到。

当一个饥饿的哲学家得到了两只筷子,他就可以用 图5-13哲学家就餐问题餐(例如意大利通心粉)。当他用餐完毕,他就放下 筷子并再次开始思考。

对上述问题的一个简单的解决方案是为每只筷子设置一个信号量,一个哲学家通过在相 应信号量上执行P操作拿起一只筷子,通过执行V操作放下一只筷子。5个信号量构成一个 的数组:

Repeat 思考

P(chopstick[i]); {拿左筷子}

P(chopstick[(i+1)DOM5]); {拿右筷子}

用餐

V(chopstick[i]); {放左筷子}

V(chopstick[(i+1)MOD5]); {放右筷子} Until false;

以上解法虽然可以保证互斥使用筷子,但有可能产生死锁。假设5个哲学家同时拿起各 自左边的筷子,于是5个信号量的值都为0,此时,当每一个哲学家企图拿起他右边的筷子时,便出现了循环等待的局面——死锁。

为了防止死锁的产生,可以采用资源的有序分配法,规定每个哲学家想用餐时总是先拿 编号小的筷子再拿编号大的筷子就不会出现死锁现象。因此,哲学家i(1<i<4)进程的程序仍然不变,而第5个哲学家进程的程序可作如下改进:

Repeat

思考

P(chopstick[1]); {拿左筷子}

P(chopstick[(5)]); {拿右筷子}

用餐

V(chopstick[1]); {放左筷子}

V(chopstick[(5)]); {放右筷子}

Until false;

下面分析一下,当每个哲学家都想就餐时,可能有4个哲学家都已拿到了自己左边的一 支筷子,而剩下的第5个哲学家拿不到编号小的筷子(一定被某个哲学家拿走)而等待, 该哲学家不可能去拿另一支筷子。因此,4个哲学家中的一个哲学家就有机会拿起其右边的 筷子而可以用餐,就餐后放下一双筷子,以使另一个哲学家又可得到右边的筷子去用餐,同 样地,其他哲学家也都先后可吃到饭,从而防止了死锁。

一般,为了提高资源的利用率,通常应当按照大多数进程使用资源的次序对资源进行编 号。先使用者编号小,后使用者编号大。

这种硬性规定申请资源的方法,会给用户编程带来限制,按照编号顺序申请资源增加了 资源使用者的不便;此外,如何合理编号是一件困难的事情,特别当系统添加新设备类型 时,会造成不灵活、不方便;如果有进程违反规定,则仍可能发生死锁。资源有序分配法与 资源静态分配策略相比,显然提高了资源利用率,进程实际需要申请的资源不可能完全与系 统所规定的统一资源编号一致,为遵守规定,暂不需要的资源也要提前申请,仍然会造成资 源的浪费。

操作系统中经典的死锁的问题操作系统中经典的死锁的问题 qq_32001201 发布了0 篇原创文章 · 获赞 0 · 访问量 1152 私信 关注
上一篇:多线程面试题——哲学家就餐问题(Java)


下一篇:哲学家进餐问题解决思路 JAVA实现