Concept of semaphores in operating system

Published: Last Edited:

This essay has been submitted by a student. This is not an example of the work written by our professional essay writers.


Semaphore is a mechanism to resolve resources conflicts by tallying resource seekers what is the state of sought resources, achieving a mutual exclusive access to resources. Often semaphore operates as a type of mutual exclusive counters (such as mutexes) where it holds a number of access keys to the resources. Process that seeks the resources must obtain one of those access keys, one of semaphores before it proceeds further to utilize the resource. If there is no more such a key available to the process, it has to wait for the current resource user to release the key.


There are two kinds of semaphores:

  1. Readers/writer locks
  2. Counting semaphores, though the readers/writer lock style of semaphore is preferred.

A readers/writer lock semaphore contains no explicit reference associating it with the shared data it protects. You maintain the association simply by programming cooperating threads to acquire the semaphore before accessing the data. This style of programming allows multiple threads (readers) to read the data associated with the semaphore simultaneously, but allows only one thread at a time (a writer) to modify the data.


There are two kinds of readers/writer lock semaphores:

1) local semaphores: it can only be used within tasks

2) recoverable semaphores: it can be shared among tasks. A recoverable semaphore has the ability to recover when the thread holding the semaphore unexpectedly terminates without releasing the semaphore; in this case, the recoverable semaphore restores itself to an unlocked state and unblocks any threads waiting to acquire it. This capability is essential for preventing deadlocks involving semaphores that are shared among tasks.


Semaphores can only be accessed by two operations (they will be system calls)



semaphore S shared integer variable usually initialized to 1

P(S): trap to the kernel

disable interrupts (so semaphore access is atomic)

if S > 0 then S := S - 1

else { queue the process on S, change its state to blocked,

schedule another process }

enable interrupts


V(S): trap to the kernel

disable interrupts

if S = 0 and queue on S is not empty then

{ pick a process from the queue on S,

change its state from blocked to ready }

else S := S + 1

enable interrupts


if we have a shared-memory multiprocessor instead of a single-processor, then disabling interrupts to access S atomically is not good enough since disabling interrupts on one processor has no effect on another processor instead we use test_and_set on a lock variable internal to the kernel, where there is a lock variable for each semaphore a test_and_set which busy waits internal to the OS is not considered a busy-waiting solution to the mutual exclusion problem because the process doing the P operation is blocked if S is 0 or we can lock the bus and unlock it when done Now we can implement

mutex_begin: P(S)

mutex_end: V(S)

Semaphores can be used in two ways

1. mutual exclusion to avoid race conditions in accessing shared data in critical sections in concurrently executing processes

P(S) count++ V(S) /* S only takes on values 0, 1 */

S is called a binary semaphore

2. process synchronization (also called condition synchronization)

3. P(empty) ... V(full)

4. P(full) ... V(empty)

Therefore semaphore represents the number of resources available and is called as counting semaphores