Locks as a solution to race conditions
Intuitively, since the race conditions that we observed arose when multiple threads or processes accessed and wrote to a shared resource simultaneously, the key idea behind solving race conditions is isolating the executions of different threads/processes, especially when interacting with a shared resource. Specifically, we need to make sure that a thread/process can only access the shared resource after any other threads/processes interacting with the resource have finished their interactions with that resource.
With locks, we can turn a shared resource inside a concurrent program into a critical section, whose integrity of data is guaranteed to be protected. We will see this in action next.
The effectiveness of locks
A critical section guarantees the mutual exclusion of a shared resource and cannot be accessed concurrently by multiple processes or threads; this will prevent any protected data from being updated or altered with conflicting...