Problem:
Males and Females can use a unisex bathroom.
The bathroom has infinite capacity but Males and Females cannot use the bathroom at the same time.
I'm having trouble enforcing the sex-segregation provision. I'm trying to use the LightSwitch design pattern from "Little Book of Semaphores" and I can't figure out why the pattern isn't excluding the opposite sex when a male or female is in the bathroom.
This isn't a homework problem. It's a problem I bombed on in an interview.
Users.py:
class User(object):
def __init__(self, cv, sex, line_full_event):
self.cv = cv
self.sex = sex
self.line_full_event = line_full_event
def enter_bathroom(self, bathroom):
with self.cv:
bathroom.enter(self.sex, self.cv)
def leave_bathroom(self, bathroom):
bathroom.leave(self.sex, self.cv)
class Male(User):
def __init__(self, cv, sex, line_full_event):
super(Male, self).__init__(cv, sex, line_full_event)
def go(self, bathroom):
logging.debug("Male queueing up")
self.line_full_event.wait()
super(Male, self).enter_bathroom(bathroom)
super(Male, self).leave_bathroom(bathroom)
class Female(User):
def __init__(self, cv, sex, line_full_event):
super(Female, self).__init__(cv, sex, line_full_event)
def go(self, bathroom):
logging.debug("Female queueing up")
self.line_full_event.wait()
super(Female, self).enter_bathroom(bathroom)
super(Female, self).leave_bathroom(bathroom)
LightSwitch.py:
class LightSwitch:
def __init__(self):
self.mutex = Lock()
self.count = 0
def inc(self, cv):
with self.mutex:
self.count += 1
logging.debug("inc-ing! count == %d", self.count)
if self.count == 1:
cv.acquire()
def dec(self, cv):
with self.mutex:
self.count -= 1
logging.debug("dec-ing! count == %d", self.count)
if self.count == 0:
cv.notify_all()
cv.release()
Bathroom.py
MALE = 1
FEMALE = 0
class Bathroom:
def __init__(self):
self.male_switch = LightSwitch()
self.female_switch = LightSwitch()
def enter(self, sex, cv):
if sex == MALE:
self.female_switch.inc(cv)
elif sex == FEMALE:
self.male_switch.inc(cv)
def leave(self, sex, cv):
if sex == MALE:
self.female_switch.dec(cv)
elif sex == FEMALE:
self.male_switch.dec(cv)
Main.py:
def Main():
logging.basicConfig(format='%(threadName)s, %(asctime)s, %(message)s', datefmt='%M:%S', level=logging.DEBUG)
# create Bathroom
b = Bathroom()
# create whatever threading objects we need
males_can_enter, females_can_enter = get_cvs()
line_full = threading.Event()
for i in range(10):
if random.randint(0,1) == MALE:
# create Male user
user = Male(males_can_enter, MALE, line_full)
else:
# create Female user
user = Female(females_can_enter, FEMALE, line_full)
t = threading.Thread(target=user.go, args=(b,))
t.start()
logging.debug("we're off to the races!")
line_full.set()
def get_cvs():
return (threading.Condition(), threading.Condition())
if __name__ == '__main__':
Main()
Aucun commentaire:
Enregistrer un commentaire