0
0
Operating-systemsConceptBeginner · 3 min read

Counting Semaphore: Definition, Usage, and Examples

A counting semaphore is a synchronization tool used in operating systems to control access to a limited number of resources. It maintains a count representing available resources and blocks or allows processes based on this count.
⚙️

How It Works

A counting semaphore works like a ticket system for a limited resource. Imagine a parking lot with a fixed number of parking spots. The semaphore's count is like the number of free spots available. When a car (process) arrives, it takes a ticket (decreases the count). If no tickets are left, the car must wait until a spot frees up.

When a process finishes using the resource, it returns the ticket (increases the count), allowing another waiting process to proceed. This way, the semaphore ensures that no more than the allowed number of processes use the resource simultaneously, preventing conflicts and resource overuse.

💻

Example

This example shows a simple counting semaphore controlling access to a resource pool of size 3. Multiple threads try to enter the critical section, but only 3 can enter at once.

python
import threading
import time

class CountingSemaphore:
    def __init__(self, initial):
        self.count = initial
        self.lock = threading.Lock()
        self.condition = threading.Condition(self.lock)

    def acquire(self):
        with self.condition:
            while self.count == 0:
                self.condition.wait()
            self.count -= 1

    def release(self):
        with self.condition:
            self.count += 1
            self.condition.notify()

semaphore = CountingSemaphore(3)

def worker(id):
    print(f"Worker {id} is waiting to enter")
    semaphore.acquire()
    print(f"Worker {id} has entered")
    time.sleep(1)  # Simulate work
    print(f"Worker {id} is leaving")
    semaphore.release()

threads = []
for i in range(6):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()
Output
Worker 0 is waiting to enter Worker 0 has entered Worker 1 is waiting to enter Worker 1 has entered Worker 2 is waiting to enter Worker 2 has entered Worker 3 is waiting to enter Worker 4 is waiting to enter Worker 5 is waiting to enter Worker 0 is leaving Worker 3 has entered Worker 1 is leaving Worker 4 has entered Worker 2 is leaving Worker 5 has entered Worker 3 is leaving Worker 4 is leaving Worker 5 is leaving
🎯

When to Use

Counting semaphores are useful when you have a limited number of identical resources that multiple processes or threads need to share. For example:

  • Controlling access to a fixed number of database connections.
  • Managing a pool of worker threads or hardware devices.
  • Limiting concurrent access to a section of code that can only handle a certain number of users.

They help prevent resource conflicts and ensure fair usage without overloading the system.

Key Points

  • A counting semaphore tracks how many resources are available.
  • Processes decrease the count when using a resource and increase it when done.
  • If no resources are free, processes wait until one becomes available.
  • It helps manage concurrent access to limited resources safely.

Key Takeaways

A counting semaphore controls access to multiple identical resources by maintaining a count.
It blocks processes when no resources are available and wakes them when resources free up.
Use counting semaphores to manage pools like connections, threads, or devices.
They prevent conflicts and resource overuse in concurrent systems.