Python单车道桥实现中的死锁
我正在尝试学习如何在Python中使用信号量进行同步。我有一个设置,感觉应该可以正常工作,但我总是遇到死锁的问题。这就像经典的单车道桥问题,任何数量的车只要朝同一个方向行驶就可以通过。我并不太担心饥饿的问题,我知道如果一个方向有无限的车流,另一个方向就会被堵住。我只是想让这个信号量的功能正常工作。我觉得这个应该可以正常运作,也许是Python的问题?我觉得在资源(桥)不可用时,获取信号量应该会被阻塞,但似乎并不是这样。非常感谢大家的意见!
class OneLaneBridge(object):
"""
A one-lane bridge allows multiple cars to pass in either direction, but at any
point in time, all cars on the bridge must be going in the same direction.
Cars wishing to cross should call the cross function, once they have crossed
they should call finished()
"""
def __init__(self):
self.dir = -1
self.bridge_access = Semaphore()
self.cars_on_bridge = 0
self.mutex = Semaphore()
def cross(self,direction):
"""wait for permission to cross the bridge. direction should be either
north (0) or south (1)."""
self.mutex.acquire()
if(self.dir == -1): #direction has been reset
self.dir = direction
if(direction == self.dir): #cars already going this direction
if(self.cars_on_bridge == 0): #first car in this direction acquires lock
self.bridge_access.acquire()
#there's now another car on the bridge
self.cars_on_bridge += 1
else:
#block the car and add it to waiting queue (this is how semaphores work?)
self.bridge_access.acquire()
self.mutex.release()
def finished(self,direction):
self.mutex.acquire()
self.cars_on_bridge -= 1 #car is now off the bridge
if(self.cars_on_bridge == 0): #no more cars on bridge so release access
self.bridge_access.release()
self.dir = -1 #reset the direction so the next car will dictate the direction
self.mutex.release()
编辑:
问题出在cross()方法上,正如大家所指出的那样。问题是互斥锁没有被释放,导致了死锁。而一旦互斥锁被释放,车子不再被阻塞时,它们的处理方式也没有像其他车那样正确。这里是新的cross方法,大部分改动在else块中:
def cross(self,direction):
"""wait for permission to cross the bridge. direction should be either
north (0) or south (1)."""
self.mutex.acquire()
if(self.dir == -1):
self.dir = direction
if(direction == self.dir):
if(self.cars_on_bridge == 0):
self.bridge_access.acquire()
self.cars_on_bridge += 1
else:
self.mutex.release()
self.bridge_access.acquire()
self.mutex.acquire()
self.cars_on_bridge += 1
self.dir = direction
self.mutex.release()
self.mutex.release()
1 个回答
1
当一辆车朝错误的方向驶入cross
时,它会一直占用一个叫做“互斥锁”的东西,这样其他线程在尝试获取这个互斥锁时就会出现死锁的情况,也就是大家都在等对方,谁也动不了。
而且,当一辆朝错误方向的车在cross
中解除阻塞后,它其实还没有开始过桥。你还需要设置正确的行驶方向,并增加在桥上的车的数量,因为你之前只在车朝正确方向时做了这些。如果你只是释放互斥锁然后返回,就像你的代码试图做的那样,调用cross
的地方会认为这辆车已经被允许上桥了。