~/problems / Coordination / Condition variable

Basics: countdown latch

easy basics ~10 min

A latch lets some threads wait until count other events have happened, for example "wait until all 3 services have finished starting".

Implement Latch(count):

  • count_down(): decrease the count by 1. It never goes below 0; extra calls do nothing.
  • wait(timeout=None) -> bool: block until the count reaches 0, then return True. If timeout seconds pass first, return False. If the count is already 0, return True right away.
  • get_count() -> int: the current count.

Any number of threads may be waiting at once, and all of them must wake up when the count hits 0.

latch = Latch(2)
# thread A: latch.wait()        -> blocks
# thread B: latch.count_down()  -> count 1, A still blocked
# thread C: latch.count_down()  -> count 0, A returns True
latch.wait(timeout=0.1)         # True immediately: already 0

Latch(1).wait(timeout=0.05)     # False after ~0.05s: nobody counted down

Constraints: count >= 0. Don't sleep or busy-wait.

Show hint

Keep the count behind one threading.Condition: wait uses cond.wait_for(lambda: self.count == 0, timeout) (it re-checks after every wake-up and returns the predicate's value), and count_down calls notify_all() so every waiter re-checks.

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

0:00
Ctrl ' run · Ctrl ↵ submit
esc