← Questions

Reusable cyclic barrier for a fixed number of threads

0
AppleCodingLast asked Aug 2026

Implement a cyclic barrier for a fixed number of threads (parties). Each thread calls wait() at a sync point; the call blocks until all parties have called it in this round, then all of them are released together. The barrier then resets by itself, so the same threads can use it round after round. Build it from a mutex and condition variables (or your language's monitor), not from a library barrier, latch, phaser or semaphore helper.

Interface

Unless you agree on a different interface with the interviewer, assume:

  • CyclicBarrier(parties: int) — parties >= 1.
  • wait() -> None — blocks until parties threads have called wait() in the current round.

Example

b = CyclicBarrier(3)
threads T1, T2, T3 each loop 5 times:  do step i; b.wait()
no thread starts step i + 1 before all three finished step i,
and the same barrier serves all 5 rounds

T1 and T2 call wait()      ->  both block
T3 calls wait()            ->  all three return; the round count is back to 0
T1 calls wait() at once    ->  T1 blocks in round 2, even if T2 has not woken yet

Constraints

  • Any number of consecutive rounds without re-creating the barrier.
  • No busy-waiting in the main version.
  • No thread leaves a round early, and no thread is counted in the wrong round.

Clarifying questions

  • Which primitives are allowed: mutex and condition variables, or only atomics?
  • Should an optional action run once per round, in the last thread to arrive?
  • If a waiter times out or is interrupted, does the barrier break for everyone in the round?
  • Should wait() return the thread's arrival index?

What a strong answer covers

  • Counting arrivals under the lock; the last arrival resets the count and wakes everyone with a broadcast.
  • A generation (round) number: each waiter remembers its generation and waits until it changes, so a fast thread that re-enters cannot be counted in the old round or release it.
  • Waiting in a loop that tolerates spurious wakeups.
  • Failure semantics: timeout, interruption, an exception in the round action, resetting a broken barrier.
  • A spinning version on atomics (sense-reversing barrier) and when spinning beats sleeping.
  • A test that actually exposes the reuse race.

Follow-ups

  • Rebuild it with only atomic operations and spinning.
  • Add wait(timeout). What happens to the others when one times out?
  • The per-round action throws. What state is the barrier in, and what do the other threads see?
  • How do you write a test that reliably catches a barrier that breaks on reuse?
Write and test your solution herePython in your browser, the question's tests level by level, every submission kept for you.Sign in to start coding