python单线桥实现中的死锁

时间:2014-07-18 21:37:07

标签: python multithreading python-2.7 deadlock semaphore

所以我试图在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()方法中,正如所指出的那样。问题在于互斥锁没有被释放导致死锁,并且一旦互斥锁被释放并且汽车不再被阻挡,它们就不会像其他汽车一样被妥善处理。这是一个新的交叉方法,其中大部分更改都在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 个答案:

答案 0 :(得分:1)

当一辆汽车在cross中走错方向时,它仍将持有互斥锁,因此当他们试图获取互斥锁时,其他线程将会死锁。

同样,一旦汽车朝着错误的方向解锁cross,它仍然没有开始穿越。您仍然需要设置方向并增加桥上汽车的数量,因为您只是在汽车行驶方向正确时才这样做。如果您只是释放互斥锁并返回,就像您的代码正在尝试进行操作一样,cross的调用者将认为该汽车已被允许进入该桥。