Latticework

Command Palette

Search for a command to run...

Concurrency

Detecting Race Conditions

16 min

Explanation

Rather than staring at an interleaving and reasoning about it by hand, you can check correctness mechanically: if N increments happen, the final value should be exactly initial_value + N — no more, no less. Any interleaving where the actual result falls short reveals a lost update, definitively, without needing to trace through the schedule step by step.

def is_race_safe(schedule, initial_value=0):
    final = simulate_race(schedule, initial_value)
    num_writes = sum(1 for _, step in schedule if step == "write")
    return final == initial_value + num_writes
Try it

This 'expected count vs. actual result' comparison is a general debugging technique, not just for concurrency -- it's the same idea as a checksum: derive an independently-computable expected value, then check the real system against it.

Loading editor…
Exercise

Using the provided `simulate_race` from the previous module, write `is_race_safe(schedule, initial_value=0)`: return True if the final value equals `initial_value` plus the number of `'write'` steps in the schedule (i.e. no update was lost), False otherwise.

Quiz

What makes `is_race_safe` a useful way to think about race-condition testing?

Checkpoint

You can mechanically detect whether a specific thread interleaving lost an update, by comparing the actual result against the mathematically expected one.