Introduction
Thread synchronization primitives like Lock, RLock, Semaphore, and Event coordinate access to shared resources in multithreaded programs.
Lock
import threading
class Counter:
def __init__(self):
self.value = 0
self.lock = threading.Lock()
def increment(self):
with self.lock:
self.value += 1
def get(self):
with self.lock:
return self.value
counter = Counter()
threads = [threading.Thread(target=counter.increment) for _ in range(1000)]
for t in threads:
t.start()
for t in threads:
t.join()
print(counter.get()) # 1000
RLock (Reentrant Lock)
import threading
lock = threading.RLock()
def outer():
with lock:
print("outer")
def inner():
with lock # Same lock can be acquired again
print("inner")
def nested():
with lock:
outer()
inner()
nested() # Works with RLock, would deadlock with Lock
Semaphore
import threading
import time
# Limit to 3 concurrent connections
semaphore = threading.Semaphore(3)
def worker(n):
with semaphore:
print(f"Worker {n} started")
time.sleep(1)
print(f"Worker {n} finished")
threads = [threading.Thread(target=worker, args=(i,)) for i in range(10)]
for t in threads:
t.start()
for t in threads:
t.join()
Event
import threading
import time
event = threading.Event()
def worker(n):
print(f"Worker {n} waiting")
event.wait() # Block until set
print(f"Worker {n} proceeding")
threads = [threading.Thread(target=worker, args=(i,)) for i in range(3)]
for t in threads:
t.start()
time.sleep(2)
event.set() # Release all waiting threads
Condition
import threading
class BoundedBuffer:
def __init__(self, size=5):
self.buffer = []
self.size = size
self.lock = threading.Condition()
def put(self, item):
with self.lock:
while len(self.buffer) >= self.size:
self.lock.wait()
self.buffer.append(item)
self.lock.notify()
def get(self):
with self.lock:
while not self.buffer:
self.lock.wait()
item = self.buffer.pop(0)
self.lock.notify()
return item
Practice Problems
- Implement thread-safe counter with Lock
- Use RLock for recursive operations
- Control concurrent access with Semaphore
- Coordinate threads with Event
- Implement producer-consumer with Condition