---
title: "Producer-consumer using semaphore"
subject: "Operating System"
chapter: 3
key: "semester_6/operating_system:pc-semaphore-mutual-exclusion"
source: https://www.bctengineer.com/q/semester_6/operating_system/pc-semaphore-mutual-exclusion
site: BCT Engineering
---

# Producer-consumer using semaphore

Operating System · Chapter 3: Process Communication and Synchronization

- Asked in: 2069 Bhadra, 2+8 marks; 2070 Magh, 3+5 marks; year not given (asked 2 times)
- Video: [Bounded Buffer Problem|Problems Of Synchronization part1| producer consumer problem using semaphore](https://www.youtube.com/watch?v=yw__NPExEH4) — Sudhakar Atchala
- Answer checked by Claude Opus 5.5 (high effort) on 2026-10-14
- Page: https://www.bctengineer.com/q/semester_6/operating_system/pc-semaphore-mutual-exclusion
- Whole chapter: https://www.bctengineer.com/md/semester_6/operating_system/chapter-3

## Question

What are the conditions to get mutual exclusion? Define semaphore and solve the producer-consumer problem using semaphore.

## Answer

#### Conditions for mutual exclusion

For a correct solution to the critical-section (mutual exclusion) problem, four conditions must hold (Tanenbaum):

1. No two processes may be **inside their critical regions at the same time**.
2. No assumptions may be made about **speeds or the number of CPUs**.
3. No process running **outside** its critical region may block other processes.
4. No process should have to **wait forever** to enter its critical region (no starvation, i.e. bounded waiting).

#### Semaphore

A **semaphore** is an integer variable (introduced by Dijkstra) that can be accessed only through two atomic operations, `down` (P / wait) and `up` (V / signal). It is used for mutual exclusion and for synchronization of processes.

```c
down(S):  if (S > 0) S = S - 1;
          else block the calling process (put it on S's queue);
up(S):    if (some process is blocked on S) wake up one of them;
          else S = S + 1;
```
Both operations are indivisible: once started, no other process can access S until the operation finishes or blocks.

A semaphore initialised to 1 is a **binary semaphore (mutex)**; one initialised to n counts resources.

#### Producer-consumer (bounded buffer) problem

A producer puts items into a shared buffer of N slots; a consumer removes them. The producer must wait when the buffer is full and the consumer must wait when it is empty, and they must not touch the buffer at the same time.

Three semaphores are used:
- `mutex = 1`: mutual exclusion on the buffer.
- `empty = N`: counts empty slots (blocks producer when 0).
- `full = 0`: counts filled slots (blocks consumer when 0).

```c
#define N 100                 /* number of slots in the buffer */
typedef int semaphore;
semaphore mutex = 1;          /* controls access to the buffer */
semaphore empty = N;          /* counts empty slots */
semaphore full  = 0;          /* counts full slots */

void producer(void) {
    int item;
    while (TRUE) {
        item = produce_item();    /* make an item */
        down(&empty);             /* wait for an empty slot */
        down(&mutex);             /* enter critical region */
        insert_item(item);        /* put item in buffer */
        up(&mutex);               /* leave critical region */
        up(&full);                /* one more full slot */
    }
}

void consumer(void) {
    int item;
    while (TRUE) {
        down(&full);              /* wait for a full slot */
        down(&mutex);             /* enter critical region */
        item = remove_item();     /* take item from buffer */
        up(&mutex);               /* leave critical region */
        up(&empty);               /* one more empty slot */
        consume_item(item);       /* use the item */
    }
}
```

**Working**: the producer does `down(empty)` first, so it sleeps if there is no room; then `down(mutex)` to access the buffer. The consumer does `down(full)` and sleeps if the buffer is empty. `up(full)`/`up(empty)` wake the other process. Doing `down(mutex)` before `down(empty)` would cause deadlock (the producer holding the mutex while sleeping on a full buffer), so the order matters.

## Check yourself

The answer's key points as multiple-choice questions, with the correct option and why.

1. Which is NOT one of the four conditions for a correct mutual exclusion solution?
   A. No two processes in their critical regions at the same time
   B. No process outside its critical region may block others
   C. Assumptions about CPU speed must be made
   D. No process waits forever to enter
   Answer: C. The condition is that NO assumptions may be made about speeds or the number of CPUs. (Key point: Mutual exclusion conditions)

2. What does down(S) do when S is 0?
   A. Increments S
   B. Blocks the calling process on S's queue
   C. Returns an error
   D. Sets S to 1 and continues
   Answer: B. If S > 0 it decrements; otherwise the process is blocked until another process does up. (Key point: Semaphore down operation)

3. In the bounded-buffer solution, what does the semaphore 'empty' (initialised to N) do?
   A. Gives mutual exclusion on the buffer
   B. Counts filled slots and blocks the consumer
   C. Counts empty slots and blocks the producer when 0
   D. Counts the number of consumers
   Answer: C. empty counts free slots; the producer does down(empty) and sleeps if no slot is free. (Key point: Producer-consumer semaphores)

4. What happens if the producer does down(mutex) before down(empty)?
   A. Nothing; the order is irrelevant
   B. The consumer starves of items only briefly
   C. Items are produced twice
   D. Deadlock: the producer may sleep on a full buffer while holding the mutex
   Answer: D. Holding the mutex while sleeping on a full buffer stops the consumer from entering to free a slot. (Key point: Order of down operations)

## Related in Operating System

- [Producer-consumer: semaphore and messages](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Apc-semaphore-message-passing) — Operating System, chapter 3
- [Semaphore for mutual exclusion](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Asemaphore-enforce-mutual-exclusion) — Operating System, chapter 3
- [TSL; producer-consumer using monitors](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Apc-monitors-tsl) — Operating System, chapter 3
- [Race condition; mutual exclusion requirements](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Arace-mutual-exclusion-requirements) — Operating System, chapter 3
- [Critical section; mutual exclusion](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Acritical-section-mutual-exclusion-pc) — Operating System, chapter 3
- [Readers-writers problem with semaphore](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Areaders-writers) — Operating System, chapter 3

## Related in other subjects

- [Token ring mutual exclusion](https://www.bctengineer.com/question.md?key=semester_7%2Fdistributed_system%3Atoken-ring-mutex) — Distributed System, chapter 6, asked 3×
- [Ricart-Agrawala mutual exclusion](https://www.bctengineer.com/question.md?key=semester_7%2Fdistributed_system%3Aricart-agrawala) — Distributed System, chapter 6, asked 2×
- [Lamport algorithm for mutual exclusion](https://www.bctengineer.com/question.md?key=semester_7%2Fdistributed_system%3Alamport-mutex) — Distributed System, chapter 6
- [Mutual exclusion via sleep and wake](https://www.bctengineer.com/question.md?key=semester_6%2Fembedded_system%3Amutual-exclusion-sleep-wake) — Embedded System, chapter 6
