因此,我正在尝试学习更多有关如何在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()
最佳答案
当行驶方向错误的汽车在cross
中阻塞时,它仍将保持互斥锁,因此其他线程在尝试获取互斥锁时将死锁。
同样,一旦汽车驶向错误的方向,它在cross
中的封锁仍未开始。您仍然需要设置方向并增加桥上的汽车数量,因为只有在汽车向正确的方向行驶时,您才需要这样做。如果您只是松开互斥锁,然后像代码中那样尝试返回,则cross
的调用者将假定已允许汽车驶入桥梁。