~/problems / Locks / Deadlock and lock ordering

Dining philosophers without deadlock

medium ~20 min

Five philosophers 0..4 sit at a round table with five forks. Philosopher p's left fork is fork p and right fork is fork (p + 1) % 5, so neighbours share a fork. A philosopher needs both forks to eat.

Each philosopher is a thread that calls, several times,

table.wants_to_eat(p, pick_left_fork, pick_right_fork, eat, put_left_fork, put_right_fork)

on one shared DiningPhilosophers() object. The five arguments after p are zero-argument functions. Your method must call each of them exactly once per call, in a valid order: pick up both forks (either order), eat(), then put both forks down (either order).

Rules the tests check:

  • A fork is held by at most one philosopher at a time: nobody calls pick_... for a fork until its previous holder has called the matching put_....
  • Every philosopher eats as many times as they asked, and every thread returns (no deadlock).

The trap: give each fork a Lock and have everyone take the left fork, then the right. If all five grab their left fork at once, nobody can ever get a right fork, and every thread waits forever.

Call pick_X only once you own fork X, and put_X before you give it up.

Show hint

The deadlock needs a cycle of philosophers each holding one fork and waiting for the next. Find a rule that makes that cycle impossible: either change the order in which some philosopher reaches for forks, or limit how many philosophers can be reaching at once.

Topic: Deadlock and lock ordering. The four conditions and how to break one.

0:00
Ctrl ' run · Ctrl ↵ submit
esc