Semaphores (counting and binary) in Operating Systems - Time & Space Complexity
When using semaphores, it's important to understand how the time to complete operations changes as more processes try to access shared resources.
We want to know how the waiting and signaling actions scale when many processes compete.
Analyze the time complexity of the following semaphore operations.
semaphore.wait() // process tries to enter critical section
// critical section code
semaphore.signal() // process leaves critical section
This code shows a process using a semaphore to control access to a shared resource.
Look at what repeats when many processes use the semaphore.
- Primary operation: Each process calls wait() and signal() once per access.
- How many times: The number of processes trying to enter the critical section.
As more processes try to enter, each must wait if the semaphore is unavailable.
| Number of Processes (n) | Approx. Operations |
|---|---|
| 10 | About 10 wait and 10 signal calls |
| 100 | About 100 wait and 100 signal calls |
| 1000 | About 1000 wait and 1000 signal calls |
Pattern observation: The total semaphore operations grow directly with the number of processes.
Time Complexity: O(n)
This means the total semaphore operations increase in a straight line as more processes try to access the resource.
[X] Wrong: "Semaphore operations take constant time regardless of how many processes wait."
[OK] Correct: When many processes wait, the system must manage a queue, so waiting time and operations grow with the number of processes.
Understanding how semaphore operations scale helps you explain synchronization efficiency and resource management clearly in real-world systems.
What if we replaced the counting semaphore with a binary semaphore? How would the time complexity change when many processes compete?
Practice
Solution
Step 1: Understand the role of semaphores
Semaphores are synchronization tools used to manage access to shared resources in concurrent systems.Step 2: Identify the correct purpose
The main goal is to avoid conflicts by controlling how many processes can access a resource at once.Final Answer:
To control access to shared resources and prevent conflicts -> Option DQuick Check:
Semaphore controls resource access = A [OK]
- Confusing semaphores with memory storage
- Thinking semaphores speed up CPU
- Mixing semaphores with security functions
Solution
Step 1: Recall binary semaphore initialization
A binary semaphore can only have values 0 or 1, where 1 means resource is available.Step 2: Choose the correct initial value
Initializing with 1 means the resource is free initially, so Semaphore(1) is correct.Final Answer:
semaphore = Semaphore(1) -> Option CQuick Check:
Binary semaphore init with 1 = D [OK]
- Using 0 which blocks access initially
- Using negative values which are invalid
- Using values greater than 1 for binary semaphore
wait() on it, what will be the semaphore's value afterwards?Solution
Step 1: Understand counting semaphore behavior
Eachwait()call decreases the semaphore value by 1 if the resource is available.Step 2: Calculate the new value after three waits
Starting at 3, after threewait()calls, value = 3 - 3 = 0.Final Answer:
0 -> Option AQuick Check:
3 - 3 waits = 0 [OK]
- Thinking semaphore goes negative immediately
- Confusing wait() with signal() effects
- Assuming semaphore resets automatically
semaphore = Semaphore(1) semaphore.wait() semaphore.wait() semaphore.signal()
What is the problem with this code?
Solution
Step 1: Analyze the semaphore initial value and wait calls
The semaphore starts at 1, so the first wait() decreases it to 0 (resource taken).Step 2: Understand the effect of the second wait()
The second wait() tries to decrease from 0, so it blocks waiting for signal().Final Answer:
It causes a deadlock because the second wait() blocks indefinitely -> Option BQuick Check:
Second wait on zero blocks = deadlock A [OK]
- Thinking signal() is called twice
- Assuming semaphore initializes incorrectly
- Ignoring blocking behavior of wait()
Solution
Step 1: Understand counting semaphore limits
A counting semaphore with initial value 5 allows up to 5 concurrent accesses.Step 2: Analyze user access requests
When 7 users request access, 5 proceed immediately; the remaining 2 must wait for signal() calls.Final Answer:
Allows 5 users to access immediately; 2 users wait until others release -> Option AQuick Check:
Counting semaphore limits concurrent users = B [OK]
- Assuming all users access simultaneously ignoring limits
- Confusing counting semaphore with binary semaphore
- Thinking semaphore blocks all users at once
Ready to prove it?
Pass the test and this pattern moves unknown
