Types of Semaphore

Last Updated : 23 Feb, 2026

Semaphores are classified based on how their values are restricted and how they control access to resources. The type of semaphore determines whether only one process or multiple processes can access a resource at a time. Depending on system requirements, semaphores are mainly divided into two categories.

types_of_semaphore

Binary Semaphore

A Binary Semaphore is a synchronization mechanism that can take only two values: 0 or 1. It is mainly used to ensure exclusive access to a critical section, allowing only one process to execute at a time. The mechanism relies on atomic wait (P) and signal (V) operations to control entry and exit.

  • Value limited to 0 or 1
  • Allows single-process access to critical section
  • Uses atomic P and V operations
  • May lead to starvation if not properly scheduled

Working of Binary Semaphore

  • When the value is 1, the resource is available.
  • A process performing wait (P) changes the value to 0 and gains access.
  • If another process attempts access while the value is 0, it is blocked.

Code Implementation for Binary Semaphore:

C++
#include <iostream>
using namespace std;

class BinarySemaphore {
    int value;
public:
    BinarySemaphore() { value = 1; }

    void wait() {
        if (value == 1) {
            value = 0;
            cout << "Resource acquired\n";
        } else {
            cout << "Process blocked\n";
        }
    }

    void signal() {
        value = 1;
        cout << "Resource released\n";
    }
};

int main() {
    BinarySemaphore s;
    s.wait();
    s.wait();
    s.signal();
}
Java
/*package whatever //do not write package name here */

class BinarySemaphore {
    private int value = 1;

    public void waitSem() {
        if (value == 1) {
            value = 0;
            System.out.println("Resource acquired");
        } else {
            System.out.println("Process blocked");
        }
    }

    public void signal() {
        value = 1;
        System.out.println("Resource released");
    }
}

public class Main {
    public static void main(String[] args) {
        BinarySemaphore s = new BinarySemaphore();
        s.waitSem();
        s.waitSem();
        s.signal();
    }
}
Python
class BinarySemaphore:
    def __init__(self):
        self.value = 1

    def wait(self):
        if self.value == 1:
            self.value = 0
            print("Resource acquired")
        else:
            print("Process blocked")

    def signal(self):
        self.value = 1
        print("Resource released")


s = BinarySemaphore()
s.wait()
s.wait()
s.signal()
JavaScript
class BinarySemaphore {
  constructor() {
    this.value = 1;
  }

  wait() {
    if (this.value === 1) {
      this.value = 0;
      console.log("Resource acquired");
    } else {
      console.log("Process blocked");
    }
  }

  signal() {
    this.value = 1;
    console.log("Resource released");
  }
}

const s = new BinarySemaphore();
s.wait();
s.wait();
s.signal();


AdvantagesDisadvantages
Simple structure and easy implementationNo strict guarantee of bounded waiting
Provides exclusive access to shared resourcesPossibility of starvation
Platform-independent synchronization techniqueImproper usage can cause deadlock
Minimizes race condition risksFrequent synchronization calls may impact performance

Counting Semaphore

A Counting Semaphore is a synchronization mechanism that can take any non-negative integer value (0, 1, 2, 3, …). It is used to manage multiple instances of a shared resource, permitting more than one process to access the critical section depending on resource availability. Like binary semaphores, it uses atomic wait (P) and signal (V) operations.

  • Accepts non-negative integer values
  • Supports multiple concurrent accesses
  • Operates through atomic wait and signal
  • Maintains count of available resources
  • Suitable for identical resource pools

Working of Counting Semaphore

  • If the semaphore value is greater than 0, resources are available.
  • Each wait (P) decreases the value by 1 and allows execution.
  • When the value becomes 0, further requests are blocked.
  • Signal (V) increases the value and resumes one waiting process.

Code Implementation for Counting Semaphores:

C++
#include <iostream>
using namespace std;

class CountingSemaphore {
    int value;
public:
    CountingSemaphore(int v) { value = v; }

    void wait() {
        if (value > 0) {
            value--;
            cout << "Resource acquired\n";
        } else {
            cout << "Process blocked\n";
        }
    }

    void signal() {
        value++;
        cout << "Resource released\n";
    }
};

int main() {
    CountingSemaphore s(3);
    s.wait();
    s.wait();
    s.wait();
    s.wait();
}
Java
class CountingSemaphore {
    private int value;

    public CountingSemaphore(int v) {
        value = v;
    }

    public void waitSem() {
        if (value > 0) {
            value--;
            System.out.println("Resource acquired");
        } else {
            System.out.println("Process blocked");
        }
    }

    public void signal() {
        value++;
        System.out.println("Resource released");
    }
}

public class Main {
    public static void main(String[] args) {
        CountingSemaphore s = new CountingSemaphore(3);
        s.waitSem();
        s.waitSem();
        s.waitSem();
        s.waitSem();
    }
}
Python
class CountingSemaphore:
    def __init__(self, value):
        self.value = value

    def wait(self):
        if self.value > 0:
            self.value -= 1
            print("Resource acquired")
        else:
            print("Process blocked")

    def signal(self):
        self.value += 1
        print("Resource released")


s = CountingSemaphore(3)
s.wait()
s.wait()
s.wait()
s.wait()
JavaScript
class CountingSemaphore {
  constructor(value) {
    this.value = value;
  }

  wait() {
    if (this.value > 0) {
      this.value--;
      console.log("Resource acquired");
    } else {
      console.log("Process blocked");
    }
  }

  signal() {
    this.value++;
    console.log("Resource released");
  }
}

const s = new CountingSemaphore(3);
s.wait();
s.wait();
s.wait();
s.wait();

Explanation

  • Whenever a process executes wait(), if resources are unavailable, it is blocked and added to the queue.
  • When a process finishes and calls signal(), another waiting process is woken up to use the resource.
AdvantagesDisadvantages
Efficient management of multiple resourcesMore complex than binary semaphore
Better resource utilizationIncorrect handling may cause deadlock
Flexible and scalable synchronization methodPossible starvation without proper scheduling
Reduces idle waiting in resource poolsRequires careful coordination of operations

Wait (P) Operation

  • The wait (P) operation decreases the semaphore value by 1.
  • If the value becomes negative or zero (no resources available), the process is blocked until a resource is released.
  • It ensures that a process enters the critical section only when a resource is available.

Signal (V) Operation

  • The signal (V) operation increases the semaphore value by 1.
  • It indicates that a resource has been released.
  • If any processes are waiting, one of them is awakened and allowed to proceed.


Comment