📝 Semaphores in Process Synchronization (60 MCQs)
📖 From Operating System • 5. Process Synchronization • 60 questions available
What is Semaphores in Process Synchronization?
Definition:
A semaphore is an integer synchronization variable accessed only via atomic wait and signal operations to control access to a finite number of identical resources.
Example:
A counting semaphore initialized to allows up to three processes to enter a printer pool simultaneously, with the fourth blocking until .
Reason:
Semaphores generalize mutexes to handle both mutual exclusion () and resource counting (), providing a versatile mechanism for diverse synchronization patterns.
📝 All Semaphores in Process Synchronization MCQs
Q1. A counting semaphore S is initialized to 7. Five wait() operations and four signal() operations are performed on S in some arbitrary order. What is the final maximum possible value of S?
📖 Explanation: This question requires multi-step reasoning. Each signal() increments S, and each wait() decrements S if S>0, otherwise it blocks. The net change from 5 waits and 4 signals is -1. Starting from 7, the final value is 6. However, because waits can block when S=0, the maximum final value is achieved by performing all signals first, making S=11, then all waits, leaving S=6. The question asks for maximum possible final value, so it's 6. Option C (12) is a distractor from incorrectly adding both operations.
Q2. A system has 4 processes and 3 identical resources. Each process needs a maximum of 2 resources to complete. Can deadlock occur? If yes, what is the minimum number of resources to guarantee no deadlock?
📖 Explanation: This tests the deadlock condition with semaphores. With 3 resources and each process needing 2, deadlock can occur if each process holds 1 resource and waits for another (e.g., 4 processes each hold 0 or 1, total allocated 3, all wait). However, the key is that a process needs 2 resources to finish. With 3 resources, at most one process can get 2 resources and finish, releasing them. The system can progress. The formula for no deadlock is total resources > number of processes * (max need -1). Here, 4*(2-1)=4, so 4 resources guarantee no deadlock. Option A is a distractor from common deadlock thresholds.
Q3. Consider a semaphore S initialized to 2. Process P1 executes: wait(S); wait(S); signal(S); signal(S). Process P2 executes: wait(S); signal(S). If P1 and P2 run concurrently, which of the following is TRUE about the final value of S?
📖 Explanation: This is a classic interleaving problem. A common mistake is to assume order doesn't matter. If P1 runs entirely first: S goes 2->1->0->1->2, then P2: 2->1->2, final 2. If P2 runs first: 2->1->2, then P1: 2->1->0->1->2, final 2. However, if interleaved: P1 does first wait (S=1), P2 does wait (S=0), P1 does second wait (blocks), P2 does signal (S=1), P1 wakes and does its operations, final S? This leads to different outcomes. The correct insight is that semaphore operations are atomic, but the final value depends on the interleaving. Option C correctly identifies that the final value can be 2 or 3 depending on the execution order, which is a common misconception that it's deterministic.
Q4. Two processes, A and B, share a semaphore mutex initialized to 1. Process A: while(1) { wait(mutex); critical section; signal(mutex); } Process B: while(1) { wait(mutex); critical section; signal(mutex); } What is the primary drawback of this implementation?
📖 Explanation: This implementation uses a semaphore for mutual exclusion but doesn't address the problem of busy waiting. When a process attempts to enter the critical section and the semaphore is 0, it blocks (if it's a blocking semaphore). However, the question implies a counting semaphore which typically blocks. The primary drawback is that if processes are blocked, they consume CPU resources in a spinlock if the semaphore is implemented with busy-waiting. Option C is the correct drawback. Deadlock is not possible here because processes release the semaphore. Starvation is not inherent. Priority inversion is a separate issue with priority scheduling.
Q5. A counting semaphore is used to control access to a pool of 5 identical printers. If a process requests a printer and none are available, what happens?
📖 Explanation: This is a straightforward application of counting semaphores. A counting semaphore with initial value 5 represents the number of available printers. When a process executes wait(), if the value is >0, it decrements and proceeds. If the value is 0, the process blocks (is put to sleep) until a signal() is executed, which increments the semaphore and wakes one blocked process. This is the fundamental behavior of a blocking semaphore. Option A is incorrect because processes are not terminated. Option B describes a spinlock, which is inefficient. Option D is not a standard OS behavior.
Q6. Given the following semaphore operations: wait(S1), wait(S2), signal(S2), signal(S1). If S1=1 and S2=1, which of the following sequences will NOT cause deadlock?
📖 Explanation: This tests the order of acquiring semaphores to avoid deadlock. In option D, P1 acquires S1 then signals S2, and P2 acquires S2 then signals S1. There is no circular wait because P1 releases S2 before P2 needs it, and vice versa. In options A, B, and C, both processes hold a resource and wait for the other, creating a deadlock. Option A is the classic deadlock pattern. Option B is deadlock because both need S1 then S2, but if P1 gets S1 and P2 gets S1? Actually, if both wait for S1 first, one gets it and the other blocks, so no deadlock? Let's re-evaluate: In B, P1 waits for S1 (gets it, S1=0), then waits for S2 (gets it, S2=0), then releases. P2 waits for S1 (blocks). No deadlock. Wait, the pattern for deadlock is P1 holds S1, waits for S2; P2 holds S2, waits for S1. So A causes deadlock. D avoids deadlock. So D is correct.
Q7. A semaphore S is used to synchronize two threads: T1 produces an item and T2 consumes it. T1 executes: produce; signal(S); and T2 executes: wait(S); consume. If S is initialized to 0, what is the maximum number of items that can be consumed before any item is produced?
📖 Explanation: This is a classic producer-consumer synchronization using a semaphore. The semaphore S is initialized to 0, meaning no items are available. T2's wait(S) will block immediately because S=0. Therefore, no items can be consumed until T1 produces an item and signals S, incrementing it to 1, which wakes T2. Thus, the maximum number of items consumed before any production is 0. This tests the fundamental concept of using semaphores for condition synchronization. Option B is a distractor for those thinking signal increments to 1. Option C is for those misunderstanding the semaphore's role.
Q8. A binary semaphore is initialized to 1. Which of the following is NOT a valid use case?
📖 Explanation: A binary semaphore can only take values 0 and 1. It is perfectly suited for mutual exclusion (A) and synchronization (B). It can also be used to implement a counting semaphore (C) by using multiple binary semaphores or a more complex scheme. However, managing a pool of 10 resources directly requires a counting semaphore that can count up to 10. A binary semaphore cannot represent the number of available resources beyond 1. Option D is the correct answer because it's not a valid direct use. This requires understanding the limitations of binary vs. counting semaphores.
Q9. Consider three concurrent processes P1, P2, P3. P1 has code: wait(S1); wait(S2); ... signal(S2); signal(S1); P2: wait(S2); wait(S3); ... signal(S3); signal(S2); P3: wait(S3); wait(S1); ... signal(S1); signal(S3). If S1=S2=S3=1, what is the state?
📖 Explanation: This is a classic circular wait scenario. P1 holds S1 and waits for S2. P2 holds S2 and waits for S3. P3 holds S3 and waits for S1. This forms a circular dependency: each process holds a resource that another process needs, and all are waiting indefinitely. This is a deadlock. A common mistake is to think that because semaphores are initialized to 1, they won't deadlock. However, the order of wait operations creates a cycle. Option A is a distractor. Livelock is different (processes keep changing state without progress). Starvation is when a process is indefinitely denied resources, but here all are blocked.
Q10. A semaphore S has a queue of blocked processes. Initially S=3. After executing wait(S) four times and signal(S) two times, what is the value of S and the number of blocked processes?
📖 Explanation: Starting with S=3. Four wait() operations: if S>0, decrement. After 3 waits, S=0. The 4th wait will block, so S remains 0, and 1 process is blocked. Then two signal() operations: each increments S and if there are blocked processes, wakes one. First signal: S becomes 1, wakes the blocked process (now 0 blocked). Second signal: S becomes 2, no blocked processes. So final S=2, 0 blocked. Wait, let's re-calc: 3 waits -> S=0, 4th wait blocks (S=0, blocked=1). Two signals: first signal increments S to 1, wakes the blocked process, so blocked becomes 0. Second signal increments S to 2, blocked=0. So final S=2, 0 blocked. But option C says S=2, 0 blocked. I need to check the sequence. Actually, if we do 4 waits: 1st wait S=2, 2nd S=1, 3rd S=0, 4th blocks. So S=0, blocked=1. Then 2 signals: 1st signal increments to 1 and wakes a blocked process, so blocked=0, S=1. 2nd signal increments to 2. So final S=2, blocked=0. So correct is C.
Q11. In the producer-consumer problem with a buffer of size N, which semaphore is used to keep track of the number of empty slots?
📖 Explanation: In the standard producer-consumer solution, we use three semaphores: mutex (for mutual exclusion), full (to count the number of filled slots), and empty (to count the number of empty slots). The producer waits on empty to ensure there is space, then waits on mutex, adds item, signals mutex, and signals full. The consumer waits on full, then mutex, removes item, signals mutex, and signals empty. The semaphore that tracks empty slots is 'empty'. Option A is for mutual exclusion, B for filled slots, D is partially correct but not the primary one for empty slots.
Q12. A system has 2 semaphores S and T, both initialized to 1. Process P0: wait(S); wait(T); ... signal(T); signal(S); Process P1: wait(T); wait(S); ... signal(S); signal(T); What happens if both processes are executed?
📖 Explanation: This is the classic deadlock example. P0 acquires S (S=0), then waits for T. P1 acquires T (T=0), then waits for S. P0 holds S and waits for T; P1 holds T and waits for S. This is a circular wait, leading to deadlock. Both processes will block indefinitely. This tests the understanding of deadlock conditions, specifically mutual exclusion, hold and wait, no preemption, and circular wait. Option A is incorrect. Option C is not applicable as both are blocked. Option D is livelock, which is different.
Q13. Which of the following is TRUE about a semaphore's 'signal' operation?
📖 Explanation: The signal() operation (also known as V or up) increments the semaphore value by 1. If there are processes blocked on the semaphore, one of them is woken up. However, the atomicity of the operation ensures that the increment and wake-up are done without interruption. Option C is the most accurate. Option A is true in the sense that it increments, but it doesn't mention waking processes. Option B is false because signal() does not block; wait() does. Option D is false; any process can signal a semaphore, not just the one that waited.
Q14. A counting semaphore is used to limit the number of concurrent accesses to a database to 3. If 5 processes try to access the database simultaneously, how many processes will be blocked?
📖 Explanation: The semaphore is initialized to 3. When a process wants to access the database, it executes wait(S). If S>0, it decrements and proceeds. The first 3 processes will decrement S from 3 to 2 to 1 to 0 and proceed. The next 2 processes will find S=0 and block. So 2 processes are blocked. Option A is incorrect because the limit is 3. Option C is incorrect (that's the number that can proceed). Option D is incorrect because the first 3 proceed.
Q15. What is the primary difference between a binary semaphore and a mutex?
📖 Explanation: A binary semaphore is a semaphore that takes only 0 and 1 values. A mutex is a locking mechanism that has the concept of ownership: only the process that locked the mutex can unlock it. A binary semaphore does not have ownership; any process can signal it. This is a key difference. Option B is false because mutex is not for counting. Option C is false because both can be used for synchronization. Option D is false. This is a common interview question.
Q16. Consider a system with 3 semaphores A, B, C all initialized to 0. Process P1: signal(A); wait(B); Process P2: signal(B); wait(C); Process P3: signal(C); wait(A); What is the outcome?
📖 Explanation: This is a synchronization pattern where each process signals another and waits for a signal from another. P1 signals A, then waits for B. P2 signals B, then waits for C. P3 signals C, then waits for A. Initially, all semaphores are 0. P1 signals A (A=1), then waits for B (blocks because B=0). P2 signals B (B=1), then waits for C (blocks because C=0). P3 signals C (C=1), then waits for A (blocks because A is now 0? Wait, P1 already signaled A, so A=1, so P3's wait(A) should not block? Let's trace: P1 runs: signal(A) -> A=1, then wait(B) blocks. P2 runs: signal(B) -> B=1, then wait(C) blocks. P3 runs: signal(C) -> C=1, then wait(A) -> A=1, so it decrements A to 0 and proceeds. So P3 completes. Then it's not blocked. But P1 and P2 are blocked. So not all block. Let's re-evaluate: If P3 completes, then no deadlock. But the question says all initialized to 0. The sequence might be interleaved. If P1, P2, P3 run sequentially as listed, P1 blocks, P2 blocks, P3 completes. So P1 and P2 block, P3 completes. So not all block. But if the question expects that they all block? Let's check: If all three run concurrently, P1 signals A, P2 signals B, P3 signals C. Then P1 waits for B (B=1, so passes), P2 waits for C (C=1, passes), P3 waits for A (A=1, passes). They all complete. So the outcome depends on interleaving. The question likely expects a deadlock pattern if the semaphores are used incorrectly. However, this pattern is a cyclic dependency. If all signal first, then all wait, they complete. If they wait before signals, deadlock. The correct answer is that it depends on the order. But the options don't include that. This might be a trick question. Let's assume the intended is that they all block if the wait is executed before the signal. But since they are initialized to 0, a wait will block if no signal has occurred. In the sequential execution, P1 signals A, then waits for B (blocks because B=0). P2 signals B (wakes P1), then waits for C (blocks because C=0). P3 signals C (wakes P2), then waits for A (A is 0 because P1 used it? Actually P1 used wait(A)? No P1 didn't wait on A, it signaled A. A remains 1 after P1's signal. P3's wait(A) will decrement A to 0 and proceed. So P3 completes, P2 completes, P1 completes. So all complete. So the answer is A. But the options? The question might be flawed. Given the options, I'd say A is correct. But let's re-analyze: P1: signal(A) [A=1], wait(B) [blocks]. P2: signal(B) [B=1, wakes P1], wait(C) [blocks]. P3: signal(C) [C=1, wakes P2], wait(A) [A=1, decrements to 0, proceeds]. So P3 completes, then P2 resumes, then P1 resumes. So all complete. So answer A.
Q17. A semaphore S is initialized to -1? Is this possible?
📖 Explanation: In standard semaphore implementations, the semaphore value is never negative. It is typically a non-negative integer. A negative value would indicate an error or an invalid state. Some textbooks might define the value as the number of blocked processes (negative) but in classic Dijkstra semaphores, the value is always >=0. The wait() operation decrements the value if >0, otherwise it blocks. So initializing to -1 is not possible in standard semaphores. Option B is correct. Option A is a distractor because counting semaphores still start at >=0. Option C is incorrect because the number of blocked processes is not the semaphore value; it's a separate queue.
Q18. In a system using semaphores, a process executes wait(S) on a semaphore S with value 0. The process is put into the blocked state. Which of the following is TRUE?
📖 Explanation: When a process executes wait(S) on a semaphore with value 0, it blocks. It is added to the semaphore's waiting queue. When any process executes signal(S) (which increments the semaphore value), the operating system checks the waiting queue and wakes up one of the blocked processes (typically the first one). The woken process then completes its wait operation (which decrements the semaphore). Option A is correct. Option B describes a spinlock. Option C is false because any process can signal. Option D is false because the scheduler doesn't increment semaphores.
Q19. A counting semaphore S is used to protect a shared resource. The operations are wait(S) and signal(S). If a process is interrupted while executing wait(S) after decrementing S but before entering the critical section, what is the potential issue?
📖 Explanation: This is about the atomicity of semaphore operations. The wait(S) operation must be atomic: test the value, decrement if positive, and then allow the process to proceed. If a process is interrupted after decrementing S but before it actually enters the critical section, the semaphore value is inconsistent because the process has decremented the count but is not yet using the resource. Another process might see S=0 and block, even though the resource is not actually in use. This can lead to an inconsistent state. Option B is correct. Deadlock is a different issue. Loss of wake-up is about signals not being received. Priority inversion is about low-priority processes holding resources.
Q20. What is the maximum number of processes that can be in the critical section at the same time if protected by a binary semaphore initialized to 1?
📖 Explanation: A binary semaphore can only take values 0 and 1. When initialized to 1, it allows at most one process to enter the critical section at a time. This is the definition of mutual exclusion. Any other process attempting to enter will block until the semaphore is signaled. Option A is correct. Option B is incorrect because the semaphore would need to be initialized to 2 for that. Option C is incorrect. Option D is irrelevant.
Q21. Consider the following code for a barrier using semaphores: int count=0; semaphore mutex=1, barrier=0; // Thread i: wait(mutex); count++; if(count==N) signal(barrier); signal(mutex); wait(barrier); This barrier implementation has a flaw. What is it?
📖 Explanation: This is a common barrier implementation. The flaw is that after the barrier is passed (when count reaches N and barrier is signaled), the count is not reset. If the same threads are used for another round, the count will start from N and the barrier will be immediately passed without waiting for all threads. This is a classic error. Option A is correct. Option B is not a flaw; it's expected behavior. Option C is false because mutex protects count. Option D is false because the last thread signals and then waits on barrier, but it will be woken immediately by its own signal? Actually, the last thread signals barrier and then waits on it, but the signal will wake one thread (maybe itself or another). The common correct implementation has the last thread not waiting. So D might be a flaw too. But the primary flaw is not resetting count. Let's check: The last thread does signal(barrier) and then wait(barrier). Since it just signaled, it might be woken immediately, so it passes. But if it's woken immediately, then all threads pass. The count remains N. So next time, count is N, so condition count==N is true, and it signals barrier again, so all threads pass without waiting. So the barrier doesn't block. So A is the correct answer.
Q22. In a system with preemptive scheduling, semaphore operations are atomic. Which of the following is a necessary condition for a semaphore implementation?
📖 Explanation: For a semaphore to function correctly, its wait() and signal() operations must be atomic. This means they must be executed without interruption from other processes or threads. This is typically achieved using hardware support or by disabling interrupts. Option B is the correct necessary condition. Option A is one way to achieve atomicity but not the only way. Option C is not necessary; semaphores can be implemented in user space with hardware support. Option D is desirable but not necessary.
Q23. A set of processes uses semaphores S and T both initialized to 1. Process P: wait(S); wait(T); ... signal(T); signal(S); Process Q: wait(T); wait(S); ... signal(S); signal(T); What is the minimum number of processes needed to cause deadlock?
📖 Explanation: Deadlock requires at least two processes holding resources and waiting for resources held by the other. With two processes, P holds S and waits for T, Q holds T and waits for S. This forms a circular wait with two processes. So the minimum number is 2. Option B is correct. Option A is incorrect because a single process cannot deadlock with itself. Options C and D are incorrect because deadlock can occur with just 2.
Q24. A semaphore S is initialized to 5. Process A executes: for i=1 to 3: wait(S); Process B executes: for i=1 to 2: signal(S); If A and B run sequentially, what is the final value of S?
📖 Explanation: Sequential execution means A runs completely, then B runs (or vice versa). If A runs first: 3 wait operations decrement S from 5 to 2. Then B runs: 2 signal operations increment S from 2 to 4. So final S=4. If B runs first: 2 signals make S=7, then 3 waits make S=4. So final is always 4. Option A is correct. Option B is the initial value. Option C is if you add them. Option D is if you subtract them.
Q25. What is the main advantage of a counting semaphore over a binary semaphore for resource management?
📖 Explanation: A counting semaphore can have a value greater than 1, which makes it suitable for managing a pool of identical resources (e.g., multiple printers, memory blocks). A binary semaphore can only represent 0 or 1, so it can only manage one resource. Option A is the main advantage. Option B is false; counting semaphores are more complex. Option C is false; they don't prevent deadlock. Option D is false; both can be implemented with or without busy waiting.
Q26. Given three semaphores A, B, C initialized to 1, 0, 0 respectively. Process P1: wait(A); signal(B); Process P2: wait(B); signal(C); Process P3: wait(C); signal(A); What is the sequence of execution if all are started simultaneously?
📖 Explanation: This is a synchronization pattern where P1 must complete before P2, and P2 before P3. P1 waits on A (initially 1, so it decrements to 0 and proceeds), then signals B (B becomes 1). P2 waits on B (B=1, decrements to 0, proceeds), signals C (C=1). P3 waits on C (C=1, decrements to 0, proceeds), signals A (A becomes 1). So the only possible order is P1, then P2, then P3. Option B is correct. Option A is the same. Option C is incorrect because of dependencies. Option D is incorrect.
Q27. A system uses a semaphore S to synchronize two processes. The initial value of S is 0. Process X: wait(S); ... signal(S); Process Y: signal(S); ... wait(S); Which process must execute first for the system to work correctly?
📖 Explanation: If X executes first, it will wait on S (S=0), blocking indefinitely because Y hasn't signaled yet. If Y executes first, it signals S (S=1), then X can wait and decrement to 0 and proceed. So Y must execute first. This is a common synchronization pattern where one process signals an event that the other waits for. Option B is correct. Option A is the opposite. Option C is incorrect. Option D is incorrect because Y must go first.
Q28. In the readers-writers problem, which semaphore is used to ensure that writers have exclusive access?
📖 Explanation: In the classic readers-writers problem, a semaphore 'wrt' is used to ensure mutual exclusion for writers. When a writer wants to write, it waits on 'wrt'. Readers also wait on 'wrt' if a writer is writing, but readers can share if no writer. The 'mutex' semaphore is used to protect the read_count variable. Option D is correct. Option A is for read_count. Option B is the variable itself, not a semaphore. Option C is not standard.
Q29. A process executes wait(S) on a semaphore S with value 1. What happens to the value of S after the wait?
📖 Explanation: The wait() operation (also called P or down) decrements the semaphore value by 1 if the value is greater than 0. Since S=1, it becomes 0. The process then proceeds. Option A is correct. Option B is the original value. Option C would occur if it was 0 and it blocked (but that's not the value; it remains 0). Option D is from signal.
Q30. A semaphore S is used in a multiprocessor system. The wait(S) operation is implemented using a test-and-set instruction. This implementation has a major drawback. What is it?
📖 Explanation: When wait(S) is implemented using a busy-waiting loop (like test-and-set), the process consumes CPU cycles while waiting for the semaphore to become positive. This is called spinlock or busy waiting. On a multiprocessor system, this can be inefficient because the CPU is wasted. Option B is correct. Option A is incorrect; test-and-set doesn't cause deadlock by itself. Option C is incorrect; it provides mutual exclusion. Option D is incorrect; test-and-set is atomic.
Q31. Consider a system with 2 semaphores S and T. S=2, T=0. Process P: wait(S); signal(T); Process Q: wait(T); signal(S); If P and Q run concurrently, what is the final value of S and T?
📖 Explanation: This is a classic pattern where P waits on S and signals T, while Q waits on T and signals S. If they run concurrently, there is a potential for deadlock if P waits on S and Q waits on T simultaneously. But S=2, so P can decrement S to 1 and signal T (T=1). Q can decrement T to 0 and signal S (S=2). So both complete. Final S=2, T=0. Option A is correct. Option B is if they didn't signal. Option C is if S wasn't decremented. Option D is if T wasn't incremented.
Q32. Which of the following is NOT a property of a semaphore?
📖 Explanation: Semaphores are powerful synchronization primitives, but they do not guarantee freedom from deadlock. Deadlock can occur if semaphores are used incorrectly (e.g., circular wait). Options A, B, and C are properties of semaphores. Option D is not a property; it's a goal that requires careful programming. Option D is the correct answer. This tests the understanding that semaphores are tools, not solutions to all problems.
Q33. A binary semaphore is initialized to 0. Process A: signal(S); wait(S); Process B: wait(S); signal(S); What is the sequence of execution to avoid deadlock?
📖 Explanation: If B executes first: wait(S) blocks because S=0. So B blocks. Then A executes: signal(S) sets S=1, then wait(S) decrements to 0 and proceeds. Then B wakes up? Actually, B is blocked on wait(S). When A signals S, B wakes up and completes its wait (S becomes 0) and then signal(S) makes S=1. So both complete. If A executes first: signal(S) makes S=1, then wait(S) decrements to 0 and proceeds. Then B executes: wait(S) blocks because S=0. So B blocks forever. So the correct order is B then A to avoid deadlock. Option B is correct. Option A causes B to block indefinitely. Option C is incorrect. Option D is incorrect.
Q34. In a system with N processes competing for a resource, a counting semaphore is initialized to K (K<N). What is the maximum number of processes that can be blocked at any time?
📖 Explanation: The semaphore value K represents the number of available resources. A process can access the resource if K>0, decrementing it. When K becomes 0, subsequent processes block. If there are N processes, the first K processes will acquire the resource (decrement K to 0). The remaining N-K processes will block. So the maximum number of blocked processes is N-K. Option B is correct. Option A is the number of resources. Option C is all processes, which would only happen if K=0. Option D is N-1, which is incorrect.
Q35. A counting semaphore S is used to control access to a pool of 5 printers. The semaphore is initialized to 5. If a process calls wait(S) and the value of S is 0, what is the state of the process?
📖 Explanation: When a semaphore's value is 0, a wait() operation will block the calling process. The process is put into the semaphore's waiting queue and will be woken when a signal() is executed. Option B is correct. Option A is incorrect. Option C describes a spinlock, but standard semaphores block. Option D is incorrect because no printer is available.
Q36. What is the primary purpose of the 'mutex' semaphore in the bounded buffer problem?
📖 Explanation: In the bounded buffer (producer-consumer) problem, we use three semaphores: mutex, full, and empty. The 'mutex' semaphore (usually binary) is used to ensure that only one process (producer or consumer) accesses the buffer at a time, preventing race conditions. Option C is correct. Option A is 'full'. Option B is 'empty'. Option D is achieved by full and empty semaphores, not mutex.
Q37. Consider a semaphore S initialized to 2. Process P: wait(S); wait(S); signal(S); Process Q: wait(S); signal(S); signal(S); If P and Q run concurrently, what is the final value of S?
📖 Explanation: This requires analyzing interleavings. If P runs first: wait(S)->S=1, wait(S)->S=0, signal(S)->S=1. Then Q runs: wait(S)->S=0, signal(S)->S=1, signal(S)->S=2. Final S=2. If Q runs first: wait(S)->S=1, signal(S)->S=2, signal(S)->S=3. Then P runs: wait(S)->S=2, wait(S)->S=1, signal(S)->S=2. Final S=2. If interleaved: e.g., P: wait(S) [S=1], Q: wait(S) [S=0], P: wait(S) [blocks], Q: signal(S) [S=1, wakes P], P: signal(S) [S=2], Q: signal(S) [S=3]? Let's trace: P does first wait (S=1), Q does first wait (S=0), P does second wait (blocks), Q does signal (S=1, wakes P), P completes its wait (S=0) then signal (S=1), Q does second signal (S=2). Final S=2. So it's always 2. Option A is correct. But wait, if P does wait, wait, signal, the net effect is -1. Q does wait, signal, signal, net effect +1. Total net 0. Initial 2 -> final 2. So A is correct. Option B is a distractor.
Q38. In the dining philosophers problem, what is the minimum number of forks required to avoid deadlock if each philosopher needs two forks?
📖 Explanation: In the dining philosophers problem, there are N philosophers and N forks. Deadlock can occur if all philosophers pick up the left fork simultaneously. One solution is to reduce the number of available forks to N-1, ensuring at least one philosopher cannot pick up both forks, breaking the circular wait. Option B is correct. Option A is the standard number but can cause deadlock. Option C is not standard. Option D is the number of forks needed if each philosopher had two, but there are N forks total.
Q39. A semaphore S is implemented as a structure with an integer value and a list of blocked processes. The signal(S) operation is called when there are blocked processes. What is the order of operations in a correct implementation?
📖 Explanation: In a correct implementation of signal(S), the semaphore value is incremented first, and then if there are blocked processes, one is woken. The order matters for correctness. If you wake a process first, it might try to decrement S before it's incremented, leading to a race condition. So the correct order is: increment S, then if the value is <=0 (or if there are blocked processes), wake one. However, the classic implementation increments S and then checks if S <= 0 to wake a process. If there are blocked processes, the value is negative (in some implementations) or there is a separate queue. The most common explanation: increment the value, and if the value is <= 0, wake a process. Option A is the standard description.
Q40. What is the effect of executing signal(S) on a semaphore with value 0 and no blocked processes?
📖 Explanation: The signal() operation increments the semaphore value by 1, regardless of whether there are blocked processes. If S=0 and no processes are blocked, S becomes 1. Option A is correct. Option B is incorrect. Option C is incorrect because semaphore values are non-negative. Option D is incorrect because signal() does not block.
Q41. A system uses semaphores to synchronize three processes P1, P2, P3. The semaphores are initialized as follows: S1=1, S2=0, S3=0. P1: wait(S1); signal(S2); P2: wait(S2); signal(S3); P3: wait(S3); signal(S1); What is the sequence of execution?
📖 Explanation: This is a chain synchronization. P1 must execute first because it waits on S1 (which is 1). It then signals S2. P2 waits on S2, so it can only execute after P1 signals it. P2 signals S3, allowing P3 to execute. P3 signals S1, but that doesn't affect the order. So the only possible order is P1, then P2, then P3. Option A is correct. Option B is the reverse, which is impossible because P3 waits on S3 which is 0 initially. Option C is impossible. Option D is incorrect.
Q42. What is the output of the following pseudo-code if semaphore S is initialized to 1? Process A: wait(S); print('A'); signal(S); Process B: wait(S); print('B'); signal(S);
📖 Explanation: This is a mutual exclusion example. The semaphore S ensures that only one process can execute the critical section (print) at a time. Both processes can run in any order because the scheduler decides which process runs first. If A runs first, it prints A then B. If B runs first, it prints B then A. So the output can be AB or BA. Option C is correct. Option A and B are specific orders. Option D is impossible because each process prints once.
Q43. A semaphore S is used to limit the number of simultaneous connections to a server to 10. The semaphore is initialized to 10. What operation should a client perform when it connects?
📖 Explanation: When a client connects, it consumes a connection slot, so it should decrement the semaphore using wait(S). If the value is 0, it means no slots are available, and the client will block. When the client disconnects, it should signal(S) to release the slot. So the correct operation on connect is wait(S). Option B is correct. Option A is for disconnection. Option C is not the correct single operation. Option D is incorrect.
Q44. In a system with two processes, a binary semaphore is initialized to 1. Process P: wait(S); ... signal(S); Process Q: wait(S); ... signal(S); What happens if P executes wait(S) and then is preempted before signal(S)?
📖 Explanation: When P executes wait(S), S becomes 0, and P enters the critical section. If P is preempted before executing signal(S), the semaphore remains 0. When Q tries to execute wait(S), it will block because S=0. So Q blocks. Option A is correct. Option B is incorrect because Q cannot enter. Option C is incorrect because deadlock requires two processes holding resources. Option D is incorrect because starvation is a different condition.
Q45. What is a common mistake when implementing a producer-consumer solution with semaphores?
📖 Explanation: A common mistake is to acquire the mutex before checking the buffer state. For example, a producer might do wait(mutex); wait(empty); ... signal(full); signal(mutex). This can lead to deadlock if the buffer is full: the producer holds the mutex and blocks on empty, and no consumer can enter to consume because mutex is held. The correct order is to wait on empty (or full) first, then wait on mutex. Option D is a common mistake. Option A is not a mistake; mutex should be initialized to 1. Option B is a mistake but less common. Option C is not a mistake; it's the correct order.
Q46. A semaphore S has value 0 and a queue of blocked processes. If three signal(S) operations are executed, how many processes will be woken?
📖 Explanation: Each signal(S) operation increments the semaphore value. If there are blocked processes, a signal will wake one of them. With three signals, three processes will be woken (if there are at least three blocked). The value of S will become 3. Option D is correct. Option A is incorrect. Option B is for one signal. Option C is for two signals.
Q47. Which of the following is a disadvantage of using semaphores?
📖 Explanation: Semaphores can be implemented with busy waiting (spinlocks) if not done carefully, especially on multiprocessor systems. This wastes CPU time. Option B is a disadvantage. Option A is not necessarily true; they are well-understood. Option C is false; they are used for mutual exclusion. Option D is false; they are atomic by design.
Q48. Consider the following code with semaphores S and T initialized to 0 and 1 respectively: Process P: wait(T); wait(S); ... signal(S); signal(T); Process Q: wait(S); wait(T); ... signal(T); signal(S); What is the outcome?
📖 Explanation: This is a deadlock scenario. If P runs first: wait(T) (T=1, decrements to 0), then wait(S) (S=0, blocks). If Q runs: wait(S) (S=0, blocks). So both block. If Q runs first: wait(S) blocks (S=0). So deadlock. The pattern is that each holds a resource the other needs. Option B is correct. Option A is incorrect. Option C and D are incorrect because both block.
Q49. What is the role of the 'full' semaphore in the producer-consumer problem?
📖 Explanation: In the producer-consumer problem, the 'full' semaphore is used to count the number of filled buffers. The producer increments it after adding an item, and the consumer decrements it before removing an item. Option B is correct. Option A is 'empty'. Option C is 'mutex'. Option D is achieved by both full and empty.
Q50. A system uses a semaphore S to implement a spinlock. The spinlock code is: while (test_and_set(&S)); // critical section // reset S=0; What is the value of S after the critical section?
📖 Explanation: In a spinlock implementation using test-and-set, the lock is acquired by setting S to 1. After the critical section, the lock is released by setting S back to 0. Option A is correct. Option B is the value during the critical section. Option C is incorrect. Option D is incorrect because it changes.
Q51. Consider a system with 3 semaphores: mutex=1, empty=N, full=0. The producer does: wait(empty); wait(mutex); ... signal(mutex); signal(full); The consumer does: wait(full); wait(mutex); ... signal(mutex); signal(empty); What is the purpose of wait(mutex) in the producer?
📖 Explanation: The wait(mutex) operation in the producer ensures that while the producer is adding an item to the buffer, no other process (producer or consumer) accesses the buffer. This provides mutual exclusion. Option A is correct. Option B is the purpose of wait(empty). Option C is the purpose of signal(full). Option D is the purpose of signal(full).
Q52. A semaphore S is initialized to 3. Process P: wait(S); wait(S); signal(S); Process Q: wait(S); signal(S); signal(S); What are the possible final values of S if P and Q run concurrently?
📖 Explanation: This is a complex interleaving. The net effect of P is -1 (two waits, one signal). Net effect of Q is +1 (one wait, two signals). Total net 0. Starting from 3, final should be 3 if all operations complete. But due to blocking, some operations might not execute if S=0. However, with initial 3, it's unlikely to block. Let's check: If P runs first: wait (2), wait (1), signal (2). Then Q: wait (1), signal (2), signal (3). Final 3. If Q runs first: wait (2), signal (3), signal (4). Then P: wait (3), wait (2), signal (3). Final 3. If interleaved: e.g., P: wait (2), Q: wait (1), P: wait (0), Q: signal (1) wakes P, P: signal (2), Q: signal (3). Final 3. It seems always 3. But if the initial value was lower, it could vary. Here it's 3, so final is always 3. So option C (3 only) is correct. But the question might be a trick. Let's see if any interleaving can lead to a different value. If P does two waits and blocks, then Q does signal, etc. The final net is 0, so S=3. So C is correct.
Q53. What is the main difference between a semaphore and a condition variable?
📖 Explanation: Semaphores have a counter (memory) that retains the number of signals. Condition variables do not have memory; they are used in conjunction with a mutex and require a predicate to be checked. Semaphores can be used for counting (counting semaphores). Condition variables are always used with a mutex to protect the shared state. So all options A, B, and C are correct. Option D is the correct answer. This is a higher-level conceptual question.
Q54. In a system with a single CPU, can a process that is waiting on a semaphore be preempted?
📖 Explanation: A process that is waiting on a semaphore is in the blocked (or waiting) state. It is not in the ready or running state, so it cannot be preempted by the scheduler. It can only be woken up by a signal operation. Option B is correct. Option A is incorrect because preemption applies to running processes, not blocked ones. Option C is incorrect. Option D is incorrect because it can be woken, but not preempted.
Q55. A counting semaphore S is used to manage a pool of resources. The semaphore is initialized to K. If a process requests a resource and the semaphore value is K, what operation does it perform?
📖 Explanation: When a process requests a resource, it wants to acquire one, so it performs wait(S) to decrement the semaphore. If the value is K (>0), it decrements and gets the resource. Option A is correct. Option B is for releasing a resource. Option C is not the correct single operation. Option D is incorrect.
Q56. Consider the following code with semaphores S and T initialized to 0 and 0: Process P1: signal(S); wait(T); Process P2: wait(S); signal(T); What is the outcome if both are started?
📖 Explanation: This is a synchronization pattern. P1 signals S, then waits for T. P2 waits for S, then signals T. If P1 runs first: signal(S) sets S=1, wait(T) blocks because T=0. P2 runs: wait(S) decrements S to 0 and proceeds, signal(T) sets T=1, wakes P1. So both execute. If P2 runs first: wait(S) blocks because S=0. P1 runs: signal(S) sets S=1, wakes P2, then wait(T) blocks because T=0. P2 completes its wait (S becomes 0), then signal(T) sets T=1, wakes P1. So both execute. So both execute in either order. Option C is correct. Option A and B are specific orders. Option D is incorrect because there is no circular wait.
Q57. In the bounded buffer problem, if the buffer size is N, what is the maximum number of items that can be produced before a consumer consumes?
📖 Explanation: The producer can produce up to N items before the buffer is full. At that point, the empty semaphore becomes 0, and the producer will block on wait(empty). So the maximum number of items that can be produced without consumption is N. Option A is correct. Option B is if the buffer is implemented with a slot reserved. Option C is incorrect. Option D is incorrect because the buffer is bounded.
Q58. A semaphore S is used to protect a shared variable. The value of S is 1. Process P: wait(S); x=1; signal(S); Process Q: wait(S); x=2; signal(S); What is the final value of x?
📖 Explanation: The semaphore ensures mutual exclusion, so the operations on x are atomic. However, the order of execution between P and Q determines the final value. If P executes first, x becomes 1, then Q sets x to 2, so final x=2. If Q executes first, x=2, then P sets x=1, so final x=1. So the final value is either 1 or 2, depending on the scheduling. Option C is correct. Option A and B are specific outcomes. Option D is incorrect because it's predictable based on order.
Q59. What is the effect of executing wait(S) on a semaphore S with value 0 in a system that uses spinlocks?
📖 Explanation: In a spinlock implementation, wait(S) (or the lock acquisition) is implemented as a busy-waiting loop that repeatedly checks the semaphore value until it becomes positive. The process does not block; it consumes CPU cycles. Option B is correct. Option A is for blocking semaphores. Option C is incorrect. Option D is incorrect because it doesn't continue without acquiring the lock.
Q60. A system has 3 processes and a semaphore S initialized to 2. If two processes execute wait(S) and then one executes signal(S), what is the value of S?
📖 Explanation: Two wait operations: S goes 2->1->0. Then one signal: S goes 0->1. So final S=1. Wait, I said 1. Let's calculate: Initial 2. After 2 waits: S=0. After 1 signal: S=1. So final S=1. Option A is correct. Option B is the initial. Option C is if you added. Option D is if you did 3 waits.