In computer science, there is an abstract data type or simply a variable for controlling the access and providing useful abstraction by a number of processes to a shared resource in either a multi-user environment or in parallel programming. This abstract data type is called the ‘semaphore’.
– Semaphore can be thought of as a record storing information regarding the availability of units of a resource.
– This record has got the functions for safe adjustment of the units as they are released and acquired.
– This record can even wait form a unit to become available under certain conditions.
– The operations governing these safe adjustments should not have race conditions.
– Thus, the semaphores are also effective in preventing the race conditions.
– If you are using semaphores, it does not mean that your program does not have any such problems.
Semaphores are of two types as mentioned below:
- Counting semaphores: These semaphores are for the arbitrary resource count
- Binary semaphores: Unlike counting semaphores, these are restricted to binary count i.e., either 0 or 1. 0 indicates locked or unavailable and 1 indicates unlocked or available.
– A computer scientist from Dutch, Edsger Dijkstra was the first to come forward with the idea of semaphore in the year of 1965.
– Eventually, this concept was widely accepted by a number of operating systems.
– When a semaphore is employed for a pool of resources, only the number of free resources is tracked by the semaphore.
– It does not track these resources.
– Some additional mechanism is required for the selection of a free resource and such a mechanism may involve more than one semaphore.
– Processes are expected to follow the protocol and if even one process goes astray it can compromise the whole safety and fairness operations.
– Thus, it can lead to a program behaving in a very erratic or slow manner that may ultimately crash or hang the system.
– Various faults, a process can commit are:
- It may request a resource and won’t release it afterwards.
- It may release a resource that it never requested.
- It may hold a resource for a long time even if it is not needed.
- It may use a resource without making a request for it.
– Multi-resource deadlocks can still occur even if all rules are obeyed by the processes.
– This is because different semaphores are being used for managing the different resources.
– So naturally, conflict occurs when a process requires other resources.
Implementation of Semaphores
Now we shall see about the implementation of the semaphores. Two operations equip the semaphores namely:
1. Signal() or V: This operation is used for incrementing the value of the semaphore by 1 and if there are any waiting processes, one of them is added to the ready queue.
2. Wait() or P: this operation is used for decrementing the value of the semaphore by 1. When the value reaches the negative scale, the process running P is blocked and again put in to the queue.
– Brackets indicate that the operations are atomic operations i.e., they cannot be divided further by the processes.
– The number of resource units presently available is the value of the semaphore.
– When a resource unit is not available, the latter operation i.e., P simply sleeps.
– The V operation makes a resource available after it has been used by the process holding it.
– Any other operations other than V or P cannot change the value of the semaphore.
– Most of the operating systems come with efficient semaphore primitives for activating a waiting process after the semaphore has been incremented.
– This saves the time of the processes that otherwise would have been wasted in checking the value of the semaphore.