操作系统笔记——哲学家进餐问题

·  阅读 635

哲学家进餐问题

1.问题描述

有五个哲学家围坐在一圆桌旁,桌中央有一盘通心 面,每人面前有一只空盘,每两人之间放一把叉子。每个哲学家思考、饥饿、 然后吃通心面。为了吃面, 每个哲学家必须获得两把叉子,且每人只能直接从自己 左边或右边去取叉子。

2.分析

(1)进程:5个哲学家(活动相似)
(2)共享资源:5把叉子,互斥使用
(3)哲学家进餐前,测试叉子是否可以用(P操作),吃完后,放下叉子(V操作)
(4)哲学家各个进程之间不需要交换信息设计信号量:每把叉子一个互斥信号量forki,初值为1

3.学家问题的解法

解法一(会出现死锁)

semaphore fork[5]; 
for (int i=0;i<5;i++) 
fork[i]=1; 
cobegin 
process philosopher_i( ) 
//i= 0,1,2,3,4 
coend 
process philosopher_i( ) 
{ //i= 0,1,2,3,4 
while(true) { 
think( ); 
P(fork[i]); 
P(fork[(i+1)%5]); 
eat( ); 
V(fork[i]); 
V(fork[(i+1)%5]); 
} 
}
复制代码

当哲学家同时拿起左边或右边的叉子,就会出现死锁

解法二、至多允许四个哲学家同时吃(避免死锁)

semaphore fork[5]; 
Semaphore place=4; 
for (int i=0;i<5;i++) 
fork[i]=1; 
cobegin 
process philosopher_i() 
//i= 0,1,2,3,4 
coend 
process philosopher_i() 
{ //i= 0,1,2,3,4 
while(true) { 
think( ); 
p(place); 
P(fork[i]); 
P(fork[(i+1)%5]); 
eat( ); 
V(fork[i]); 
V(fork[(i+1)%5]); 
V(place); 
} 
}
复制代码

解法三、限定拿叉子的顺序

奇数号先取左手边的叉子,偶数号先取右手边的叉子(避免死锁)

process philosopher_i( ) 
{ //i= 1,3 
while(true) { 
think( ); 
P(fork[i]); 
P(fork[(i+1)%5]); 
eat( ); 
V(fork[i]); 
V(fork[(i+1)%5]); 
} 
} 
process philosopher_i( ) 
{ //i= 0,2,4 
while(true) { 
think( ); 
P(fork[(i+1)%5]); 
P(fork[i]); 
eat( ); 
V(fork[(i+1)%5]); 
V(fork[i]); 
} 
}
复制代码
分类:
阅读
标签:
分类:
阅读
标签: