Phase 12 of 25 · Topic 12.2

threading Module & Thread Synchronization with Lock

1Concept

Python's `threading` module spawns native OS threads. Race conditions occur when multiple threads mutate shared mutable state without synchronization. `threading.Lock()` provides mutual exclusion via context manager (`with lock:`).

2Architecture Diagram

[ Thread 1 ] ---> with lock: counter += 1 (Acquires Lock)
[ Thread 2 ] ---> Blocked until Thread 1 releases lock!

3Code Example

Python 3.12
import threading

counter = 0
lock = threading.Lock()

def safe_increment(n: int):
    global counter
    for _ in range(n):
        with lock: # Thread-safe mutual exclusion
            counter += 1

t1 = threading.Thread(target=safe_increment, args=(10_000,))
t2 = threading.Thread(target=safe_increment, args=(10_000,))

t1.start(); t2.start()
t1.join(); t2.join()

print(f"Final Thread-Safe Counter: {counter}")

4Expected Output

Final Thread-Safe Counter: 20000

5Key Takeaways

  • Always acquire locks using `with lock:` to guarantee release if exceptions occur.
  • `threading.RLock()` is reentrant: the same thread can acquire it multiple times without deadlocking.
  • `Thread.join()` blocks the calling thread until the worker thread terminates.