~/problems / Coordination / Semaphore

Laundromat washers

easy ~15 min

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 return True. If none is free, wait until one is. With a timeout (in seconds), give up after that long and return False without taking a machine; with None, 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 raise ValueError and 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.

Topic: Semaphore. Counting access to N resources; producer/consumer.

0:00
Ctrl ' run · Ctrl ↵ submit
esc