0
0
Operating-systemsConceptBeginner · 3 min read

Binary Semaphore: Definition, How It Works, and Use Cases

A binary semaphore is a synchronization tool used in operating systems to control access to a shared resource by allowing only two states: locked (0) or unlocked (1). It acts like a simple flag that ensures only one process or thread can access the resource at a time, preventing conflicts.
⚙️

How It Works

A binary semaphore works like a traffic light for a shared resource. Imagine a single-lane bridge where only one car can pass at a time. The semaphore acts as the gatekeeper, allowing one car to cross (resource access) and stopping others until the first car finishes.

It has only two states: 1 (unlocked) means the resource is free, and 0 (locked) means the resource is in use. When a process wants to use the resource, it checks the semaphore. If it is unlocked, the process locks it and proceeds. When done, it unlocks the semaphore, letting others access the resource.

This mechanism prevents multiple processes from using the resource simultaneously, avoiding errors or data corruption.

💻

Example

This example shows a simple binary semaphore using Python's threading module to control access to a shared resource.

python
import threading
import time

# Create a binary semaphore with initial value 1 (unlocked)
binary_semaphore = threading.Semaphore(1)

shared_resource = 0

def access_resource(thread_id):
    print(f"Thread {thread_id} is waiting to access the resource.")
    binary_semaphore.acquire()  # Lock the semaphore
    global shared_resource
    print(f"Thread {thread_id} has locked the resource.")
    shared_resource += 1
    print(f"Thread {thread_id} updated resource to {shared_resource}.")
    time.sleep(1)  # Simulate resource usage
    print(f"Thread {thread_id} is releasing the resource.")
    binary_semaphore.release()  # Unlock the semaphore

threads = []
for i in range(3):
    t = threading.Thread(target=access_resource, args=(i+1,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()
Output
Thread 1 is waiting to access the resource. Thread 1 has locked the resource. Thread 1 updated resource to 1. Thread 2 is waiting to access the resource. Thread 3 is waiting to access the resource. Thread 1 is releasing the resource. Thread 2 has locked the resource. Thread 2 updated resource to 2. Thread 2 is releasing the resource. Thread 3 has locked the resource. Thread 3 updated resource to 3. Thread 3 is releasing the resource.
🎯

When to Use

Use a binary semaphore when you need to control access to a single shared resource that only one process or thread can use at a time. It is ideal for simple locking mechanisms where you want to avoid conflicts or race conditions.

Common real-world examples include:

  • Controlling access to a printer so only one job prints at a time.
  • Managing access to a file to prevent simultaneous writes.
  • Synchronizing threads in a program to avoid data corruption.

Key Points

  • A binary semaphore has only two states: locked (0) and unlocked (1).
  • It ensures exclusive access to a shared resource.
  • It is simpler than counting semaphores, which allow multiple accesses.
  • Used to prevent race conditions and ensure synchronization.

Key Takeaways

A binary semaphore controls access to a resource by allowing only one user at a time.
It has two states: locked (0) and unlocked (1), acting like a simple on/off flag.
Use it to prevent conflicts when multiple processes or threads share a resource.
It is a fundamental synchronization tool in operating systems and concurrent programming.