Problem Statement
When multiple parts of a program try to change the same data at the same time, it can cause errors like lost updates or inconsistent results. Without careful control, these conflicts can crash the program or produce wrong outputs.
Jump into concepts and practice - no test required
This diagram shows multiple threads requesting access to shared data through a lock mechanism that ensures only one thread modifies the data at a time.
import threading # Before: No concurrency control shared_counter = 0 def increment(): global shared_counter for _ in range(100000): shared_counter += 1 threads = [threading.Thread(target=increment) for _ in range(2)] for t in threads: t.start() for t in threads: t.join() print(f"Counter without lock: {shared_counter}") # After: Using a lock to control concurrency shared_counter = 0 lock = threading.Lock() def increment_with_lock(): global shared_counter for _ in range(100000): with lock: shared_counter += 1 threads = [threading.Thread(target=increment_with_lock) for _ in range(2)] for t in threads: t.start() for t in threads: t.join() print(f"Counter with lock: {shared_counter}")
lock.acquire() is used to obtain the lock before accessing shared data.Thread 1: temp = counter
temp = temp + 1
counter = temp
Thread 2: temp = counter
temp = temp + 1
counter = temp
What is the possible final value of counter if it starts at 0?lock.acquire() shared_data.append(1) # Missing lock.release()