Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Semaphores in Operating System
Semaphores are integer variables used to solve the critical section problem through two atomic operations: wait and signal. They provide a synchronization mechanism that allows processes to coordinate access to shared resources safely.
How Semaphores Work
Semaphores use two fundamental operations that must be executed atomically (without interruption):
Wait Operation
The wait operation decrements the value of its argument S if it is positive. If S is zero or negative, the process blocks until the semaphore becomes positive.
wait(S)
{
while (S <= 0);
S--;
}
Signal Operation
The signal operation increments the value of its argument S, potentially waking up a waiting process.
signal(S)
{
S++;
}
Types of Semaphores
There are two main types of semaphores, each serving different synchronization needs:
Counting Semaphores
These semaphores have an unrestricted integer value domain and are used to coordinate access to a pool of resources. The semaphore count represents the number of available resources. When resources are allocated, the count decrements; when released, it increments.
Binary Semaphores
Binary semaphores are restricted to values 0 and 1, functioning similarly to a mutex. The wait operation succeeds only when the semaphore is 1, and the signal operation works when the semaphore is 0. They are often easier to implement than counting semaphores.
Example − Producer-Consumer Problem
Consider a bounded buffer scenario with one producer and one consumer:
semaphore mutex = 1; // Binary semaphore for mutual exclusion
semaphore empty = n; // Counting semaphore for empty slots
semaphore full = 0; // Counting semaphore for filled slots
Producer:
while(true) {
wait(empty); // Wait for empty slot
wait(mutex); // Enter critical section
// Add item to buffer
signal(mutex); // Exit critical section
signal(full); // Signal item produced
}
Consumer:
while(true) {
wait(full); // Wait for filled slot
wait(mutex); // Enter critical section
// Remove item from buffer
signal(mutex); // Exit critical section
signal(empty); // Signal slot is empty
}
Advantages
Semaphores enforce mutual exclusion strictly, allowing only authorized processes into critical sections.
No busy waiting − Processes block when resources are unavailable, preventing CPU wastage.
Machine independent − Implemented in microkernel code, making them portable across platforms.
Flexible resource management − Counting semaphores can manage multiple instances of resources efficiently.
Disadvantages
Programming complexity − Wait and signal operations must be implemented in correct order to prevent deadlocks.
Loss of modularity − Impractical for large-scale systems as they prevent structured system layouts.
Priority inversion − Low-priority processes may access critical sections before high-priority processes.
Debugging difficulty − Synchronization bugs can be hard to reproduce and diagnose.
Conclusion
Semaphores provide a powerful synchronization mechanism for process coordination in operating systems. While they offer efficient mutual exclusion and resource management, careful implementation is required to avoid deadlocks and maintain system modularity.
