Locks (Lock vs RLock)
A Lock allows only one thread to enter a critical section at a time.
import threading
lock = threading.Lock()
count = 0
def add():
global count
for _ in range(100_000):
with lock:
count += 1
t1 = threading.Thread(target=add)
t2 = threading.Thread(target=add)
t1.start(); t2.start()
t1.join(); t2.join()
print(count)What is a “critical section”?
Section titled “What is a “critical section”?”A piece of code that must not be interrupted by another thread while it updates shared data.
RLock (re-entrant lock)
Section titled “RLock (re-entrant lock)”An RLock can be acquired multiple times by the same thread.
Use it when:
- a function that holds a lock calls another function that tries to acquire the same lock
import threading
lock = threading.RLock()
def outer():
with lock:
inner()
def inner():
with lock:
print("safe")
t = threading.Thread(target=outer)
t.start(); t.join()Best practices
Section titled “Best practices”- Keep
with lock:blocks short. - Always acquire locks in a consistent order if using multiple locks.
🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – Basic Lock Usage
Section titled “Exercise 1 – Basic Lock Usage”Exercise 2 – Lock as Context Manager
Section titled “Exercise 2 – Lock as Context Manager”Exercise 3 – Detect Locked State
Section titled “Exercise 3 – Detect Locked State”pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading