MiddleDebuggingCommonNot answered yet
Why is this threaded counter wrong, and how to fix it?
Five threads each increment counter 100000 times, but the final value is too low.
import threading
counter = 0
def inc():
global counter
for _ in range(100000):
counter += 1
threads = [threading.Thread(target=inc) for _ in range(5)]
for t in threads: t.start()
for t in threads: t.join()
print(counter) # usually < 500000
Find and fix the bug.
Race condition: counter += 1 is a read-modify-write — not atomic at the bytecode level — so threads interleave and lose updates (the GIL guarantees per-bytecode atomicity, not multi-step operations). Fix: guard the increment with a threading.Lock (with lock: counter += 1).
- ✗Believing the GIL makes
+=atomic across threads - ✗Blaming print timing rather than lost updates
- ✗Thinking
globalalone makes the increment thread-safe
- →Why does the GIL guarantee bytecode atomicity but not statement atomicity?
- →When would
itertools.countor aqueue.Queuebe a cleaner fix than a lock?