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()

当一个方向错误的car在cross阻塞时,它仍然持有互斥锁,因此其他线程在试图获取互斥锁时将会死锁。

cross中,一旦一辆车走错方向,它仍然没有开始过马路。您仍然需要设置方向并增加桥上车辆的数量,因为您只在车辆朝着正确的方向行驶时才这样做。如果你只是释放互斥锁并返回,就像你的代码试图做的那样,cross的调用者将假设汽车已经被允许上桥。

最新更新