A laundromat has washers identical machines. Each customer is a thread.
Implement Laundromat(washers) with:
start_wash(timeout=None) -> bool: take a free machine and returnTrue. If none is free, wait until one is. With atimeout(in seconds), give up after that long and returnFalsewithout taking a machine; withNone, wait as long as it takes.finish_wash() -> None: hand a machine back, so one waiting customer can take it.- Handing back more machines than were taken is a bug in the caller:
finish_wash()must then raiseValueErrorand leave the number of machines unchanged.
shop = Laundromat(2)
shop.start_wash() # True
shop.start_wash() # True
shop.start_wash(timeout=0.1) # False after about 0.1s: both machines busy
shop.finish_wash()
shop.start_wash(timeout=0.1) # True right away
shop.finish_wash(); shop.finish_wash()
shop.finish_wash() # ValueError: all 2 machines are already free
At no moment may more than washers customers be washing, and a waiting customer must get a machine as soon as one is handed back.
Constraints: washers >= 1. Don't sleep or busy-wait.
Show hint
threading.BoundedSemaphore(washers) does all three: acquire(timeout=timeout) returns False on timeout (pass timeout=None to wait forever), and release() raises ValueError if it would go above the starting value.