Mutexes semaphores and monitors
Mutexes
Section titled “Mutexes”A mutex is a synchronization primitive that acts as a lock. To protect a critical section (CS), a process must first acquire the lock and subsequently release it.
Calls to acquire and release are implemented atomically via hardware instructions.
When waiting for the lock, the process can engage in two modes:
- busy waiting: the process continuously spins, checking if the lock has been released;
- context switch: the process yields control to the OS, which may schedule other processes until the lock is freed;
Semaphores
Section titled “Semaphores”A semaphore is an integer variable. It can be accessed via 2 indivisible atomic operations:
wait(): decrements the semaphore value. If the value is non-positive, the process blocks until a signal is received. This operation is used to acquire the resource.signal(): increments the semaphore value by 1. This operation is used to release the resource and may wake up a waiting process.
It can be used to control access to a finite number of resources. Processes attempting to decrement the semaphore when its count is zero or less must wait.
Each semaphore has an associated waiting queue where processes that call wait are put. Once a process sends a signal, the processes in the queue are put into the ready queue where they can try again to obtain the lock.
Monitors
Section titled “Monitors”A monitor abstracts shared data. Only its procedures can access or modify the shared resources, and only one process can be active within the monitor at any given time.
A monitor can be conceptualized as a high-level API that the programmer interacts with. The programmer does not need to manage concurrency primitives explicitly; the monitor ensures that all its procedures are executed mutually exclusively.