~/problems / Coordination / Condition variable

Baggage carousel

easy ~15 min

At an airport, handlers put bags on a carousel and passengers wait for their own bag. Every bag has a tag (a string); several bags may share a tag (a family checked in three suitcases).

Implement Carousel() with:

  • unload(tag) -> None: a handler puts one bag with this tag on the belt.
  • claim(tag, timeout=None) -> bool: a passenger waits until a bag with this tag is on the belt, takes it off (one bag) and returns True. With a timeout in seconds, give up after that long and return False; with None, wait as long as it takes.
  • on_belt() -> int: how many bags are on the belt right now.

Many passengers wait at once, each for a different (or the same) tag.

c = Carousel()
# passenger A: c.claim("AMS-17")          -> waits
# passenger B: c.claim("LIS-02")          -> waits
c.unload("LIS-02")                        # B returns True, A keeps waiting
c.unload("AMS-17")                        # A returns True
c.claim("NRT-99", timeout=0.1)            # False after ~0.1s
c.unload("X"); c.unload("X"); c.on_belt() # 2

A bag must go to one passenger only: two passengers waiting for the same tag and one bag means one gets True and the other keeps waiting.

Constraints: don't sleep or busy-wait.

Show hint

Keep a Counter of tags on the belt behind one threading.Condition. claim does cond.wait_for(lambda: bags[tag] > 0, timeout) and only takes the bag if that returned True; unload must call notify_all(), not notify(): a single notify() may wake a passenger waiting for a different tag, who goes back to sleep, and the right one is never woken.

Topic: Condition variable. wait_for(predicate) + notify_all; always include a termination case.

0:00
Ctrl ' run · Ctrl ↵ submit
esc