有5个哲学家共用一张圆桌,分别坐在周围的5张椅子上。在圆桌上有5个碗和5支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两支筷子时才能进餐。进餐毕,放下筷子又继续思考。请用信号量和PV操作实现这五位哲学家的同步过程的代码
时间: 2024-10-08 13:07:55 浏览: 51
这是一个经典的哲学家就餐问题,可以用信号量和P/V操作来解决。在这个场景中,我们需使用四个信号量:`forkL[i]` 和 `forkR[i]` 分别代表左侧和右侧的筷子,以及一个全局信号量 `eat` 表示餐桌是否有人正在进餐。
```python
import threading
# 初始化五个筷子和桌子状态
forkL = [threading.Semaphore(1) for _ in range(5)]
forkR = [threading.Semaphore(1) for _ in range(5)]
eat = threading.Semaphore(0)
def philosopher(i):
while True:
# 尝试获取左筷子
forkL[i].acquire()
# 检查右筷子是否可用
if forkR[(i+1)%5].try_acquire(): # (i+1)%5 避免数组边界问题
# 左右筷子都拿到了,尝试吃饭
eat.acquire()
print(f"Philosopher {i+1} is eating.")
eat.release() # 饭后释放餐桌占用权
forkR[(i+1)%5].release() # 放回右筷子
forkL[i].release() # 放回左筷子
else:
# 右筷子不可用,等待
forkL[i].release()
# 创建哲学家并开始思考
for i in range(5):
p = threading.Thread(target=philosopher, args=(i,))
p.start()
```
在这个代码中,每个哲学家循环地尝试获取左右两侧的筷子。如果能同时获取到,则说明可以吃饭,这时会先获取餐桌占用权(eat信号量),然后吃饭、释放占用权,最后放回筷子。如果右筷子不可用,哲学家会立即释放已获取的筷子,继续等待。
阅读全文